When an interface gets renamed, we first receive a libnl update with
the changed interface name.
This results in the following chain of calls:
- event_notification()
- announce_object()
- link_init()
- link_extract_type()
- link_type_from_udev()
Then link_type_from_udev() looks up the name in the udev data (getting
the previous name, because we did not yet recieve the udev notification)
and passes the name to wifi_utils_is_wifi(), which eventually calls
nm_platform_link_get_ifindex() -- doing a lookup by the old name.
Fix this, by passing the ifname from libnl to link_type_from_udev().
Also, change hack_empty_master_iff_lower_up() because it is called
from event_notification(), at a moment when the link cache possibly
does not yet know the ifindex -- so that the call chain to
link_extract_type(), link_type_from_udev(), wifi_utils_is_wifi()
again might lead to lookup for something that does not yet exist.
Note, that in this case the name would not yet exist, because we
did not yet put the libnl object into the link cache.
Signed-off-by: Thomas Haller <thaller@redhat.com>
Since vxlan is new-ish, and vxlan IPv6 support in particular has only
been in the kernel since 3.11, we include our own copy of the vxlan
netlink constants rather than depending on the installed headers.
The nla_policy struct declarations for GRE, etc, were originally
copied from the kernel sources, where they used tabs to align the "="
columns. Fix them to use spaces instead.
Also assert inside of sysctl_get() that we read the expected file
locations. Especially because now we might log the content of these
files.
Signed-off-by: Thomas Haller <thaller@redhat.com>
We don't thoroughly log the pointer values of our libnl objects,
so the logging in check_cache_items() is not usefull, it only
clutters the logfile.
Signed-off-by: Thomas Haller <thaller@redhat.com>
Remove the "silent_on_error" flag from nm_platform_sysctl_get(), and
make both get() and set() log at debug level on ENOENT and error level
on all other errors, always.
Also ensure that we don't sometimes write "failed to set 'x' to 'y':
Success" when a partial write occurs.
Such a failure can happen easily, because we now request an initial dump
to get AF_INET6 addresses in order to check for extended ifa flags support.
This is not critical, so downgrade the error log.
Signed-off-by: Thomas Haller <thaller@redhat.com>
Make sure NMPlatformGreProperties->path_mtu_discovery is always TRUE
or FALSE, even if the value from the kernel is "2" or "16" or
something. (This makes it consistent with what we do for other boolean
netlink properties.)
Before, nm_platform_ip4_address_exists(), et al. look into the cache to see
whether the address/route already exists and returned an error if it
did.
Change the semantic of the delete functions, to return success in case of
"nothing to delete". Also always try to delete the object in the
kernel. The reason is, that the cache might be out of date and the
caller really wants to delete it. So, to be sure, we always delete.
In most cases the object is actually in the cache (because that is
how the caller came to know that such an object might exist).
In those cases, the lookup was not useful either, because the object
was actually cached.
Signed-off-by: Thomas Haller <thaller@redhat.com>
- refactor delete_object() by merging with delete_kernel_object()
- allow deletion of object that we cannot find in the cache
currently. The kernel might have such an address, even if we don't
have it currently cached. In this case, fall back to @obj.
Also try to work around an issue, that we cannot delete an IPv4 route without
knowing its scope.
- suppress logging error message for NLE_NOADDR, which is a common
failure when deleting an address. But at the same time, add some more
debug logging, for NLE_NOADDR and NLE_OBJ_NOTFOUND.
Signed-off-by: Thomas Haller <thaller@redhat.com>
Adding IPv4 routes, with a non-zero host identifer fails with an
error message. Adding IPv6 addresses, does not return an error,
but it seems to have no effect.
Thus we have to make sure that the host part of routes
is always zero.
Signed-off-by: Thomas Haller <thaller@redhat.com>
This bug was present since a long time, however libnl3-v3.2.23
(commit fdd1ba220dd7b780400e9d0652cde80e59f63572) changed the returned
family of bridge link objects, which breaks NetworkManager.
This resulted in error messages such as:
DBG<4> object.c:207 nl_object_get: New reference to object 0x19c34b0, total 2
DBG<5> route/link.c:895 link_keygen: link 0x19c34b0 key (dev 9 fam 7) keysz 8, hash 0x2b2
DBG<2> hashtable.c:127 nl_hash_table_add: Warning: Add to hashtable found duplicate...
DBG<4> object.c:221 nl_object_put: Returned object reference 0x19c34b0, 1 remaining
NetworkManager[17745]: <error> [1392114373.475432] [platform/nm-linux-platform.c:1328] event_notification(): netlink cache error: Object exists
Even before the change of libnl, I saw the following error lines
<debug> [...] [platform/nm-linux-platform.c:1216] event_notification(): netlink event (type 16) for link: virbr0 (4)
<error> [...] [platform/nm-linux-platform.c:1265] event_notification(): netlink cache error: Object exists
Hence, the caching mechanism for libnl objects already had a bug.
For rtnl link objects, the identifier consists of family and ifindex.
Since in upper layers, we don't easily know the family, we need a way to find
the objects inside the cache. We do this, by only caching links of family
AF_UNSPEC.
Objects that we receive via event_notification() are never cached. They are only used
to trigger refetching the kernel_object. Their family is irrelevant, we
only need to know, that something about this ifindex changed.
For objects retrieved via get_kernel_object(), we only get link objects of
family AF_UNSPEC or AF_BRIDGE. In any case, we reset (coerce) their family
before caching. This way, inside the link cache, there are only objects with
(coerced) family AF_UNSPEC. We loose the information, which family the
link had, however we don't need it anyway.
https://bugzilla.gnome.org/show_bug.cgi?id=719905https://bugzilla.redhat.com/show_bug.cgi?id=1063290
Duplicates:
https://bugzilla.gnome.org/show_bug.cgi?id=724225https://bugzilla.redhat.com/show_bug.cgi?id=1063800
Signed-off-by: Thomas Haller <thaller@redhat.com>
Also, change the logging of nm_platform_ip._address_delete()
to log what we are about to do, *before* checking for existing
addresses.
Signed-off-by: Thomas Haller <thaller@redhat.com>
The previous implementation called nl_object_get() and nl_object_put()
each time in link_get(). As nl_object_get() and nl_object_put()
causes debug logging in libnl, this clutters the output.
Signed-off-by: Thomas Haller <thaller@redhat.com>
Add versioned NM_DEPRECATED_IN_* and NM_AVAILABLE_IN_* macros, and tag
new/deprecated functions accordingly. (All currently-deprecated
functions are assumed to have been deprecated in 0.9.10.)
Add NM_VERSION_MIN_REQUIRED and NM_VERSION_MAX_ALLOWED macros which
can be set to determine which versions will cause warnings.
With the current settings, external consumers of the
libnm-util/libnm-glib APIs will have MIN_REQUIRED and MAX_ALLOWED both
set to NM_VERSION_0_9_8 by default, meaning they will get warnings
about functions added in 0.9.10. NM internally sets
NM_VERSION_MAX_ALLOWED to NM_VERSION_NEXT_STABLE to ensure that it is
always allowed to use all APIs.
According to documentation, nl_rtgen_request() returns 0 on success.
Due to a bug (fixed upstream) in older libnl versions, nl_rtgen_request()
returns the number of bytes sent, which caused logging although
succeeding.
Signed-off-by: Thomas Haller <thaller@redhat.com>
The kernel adds a new capability to allow user space to manage
temporary IPv6 addresses. We need to detect this capability
to act differently, depending on whether NM has an older kernel
at hand.
This capability got introduced together when extending the
ifa_flags to 32 bit. So, we can check the netlink message,
whether we have such an nl attribute at hand.
Signed-off-by: Thomas Haller <thaller@redhat.com>
The kernel and libnl adds two new flags IFA_F_MANAGETEMPADDR
and IFA_F_NOPREFIXROUTE. Older versions of libnl do not recognize
this flag, so add a workaround to nm_platform_ip6_address_to_string()
to show "mngtmpaddr" and "noprefixroute", respectively.
Also, add function nm_platform_check_support_libnl_extended_ifa_flags()
that checks whether libnl supports extended ifa_flags that were
added recently.
Extended flags and the two ifa-flags above were added to libnl in close
succession.
Signed-off-by: Thomas Haller <thaller@redhat.com>
nl_socket_add_memberships expects a variadic list of int,
NULL is possibly defined as ((void *) 0) or 0L.
Signed-off-by: Thomas Haller <thaller@redhat.com>
It is common that the file exists, but cannot be read
(Operation not supported). So, silence any error when
reading the phys_port_id file.
Signed-off-by: Thomas Haller <thaller@redhat.com>
There seems to be the possibility of a race while reading tun
properties from sysctl. In this case, when being unable to
read the properties at construction of NMDeviceTun, we retry
shortly after.
- let tun_get_properties() not log any errors and it
does not stop on the first error but tries to read all
the values. Also, it initializes all fields of the output
structure with a default value (NULL).
- hard code kernel flag #ifndef in header files. Even if the
flag IFF_MULTI_QUEUE is not defined at compile time of NM,
it could still be supported by the kernel (eg. when booting
a newer kernel then the installed kernel headers). Simply
hard code the value, this value is not ever going to change
anyway.
https://bugzilla.redhat.com/show_bug.cgi?id=1034737
Signed-off-by: Thomas Haller <thaller@redhat.com>
In some cases, an error when reading the sysctl value can be expected.
In this case, we want to suppress the error message
Signed-off-by: Thomas Haller <thaller@redhat.com>
A gateway route can only be added, if there exists a device route
for that gateway. Therefore, nm_platform_ip4_route_sync() and
nm_platform_ip6_route_sync() has to add the device routes first,
before adding gateway routes.
Note: usually for all configured addresses, there is also a device
route for the subnet added by the kernel. This means, NM must first
configure the addresses before route_sync, so that these implicit device
routes already exist -- this is however already done correctly.
Signed-off-by: Thomas Haller <thaller@redhat.com>
If a route already exists that matches the network, prefix, gateway,
and metric of a route NM would like to add, don't try to overwrite
the route.
Unlike IP addresses, the kernel doesn't update the details, it
appears to completely replace that route, which might screw up
external tools that added the route originally.
One example of this is IPSec via openswan/libreswan. They add the
routes to the kernel upon connection, and if NM replaces those routes,
IPSec no longer works. While this may be due to kernel bugs or
bad handling of route replacement, there's no reason for NM to touch
routes that it wouldn't materially change anyway.
(yes, we could perhaps use NLM_F_REPLACE in add_kernel_object() only
when we really wanted to replace something, but why ask the kernel
to do the work when it's not required anyway?)
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