Add a new enum NMPlatformGetRouteMode. This extends the existing
functions nm_platform_ip4_route_get_all() and nm_platform_ip6_route_get_all()
to return default routes only.
Signed-off-by: Thomas Haller <thaller@redhat.com>
Kernel, netlink an NMPlatformRoute treat route metrics as
uint32. Fix several places to use the exact type.
Signed-off-by: Thomas Haller <thaller@redhat.com>
As we use NMLinkType in NetworkManagerUtils.h, we cannot use
the utils header without nm-platform.h. That is clearly wrong.
Apparently NMLinkType has a wider use outside of platform (and
its name is not prefixed with 'platform' either).
Move the enum definition to nm-types.h.
Signed-off-by: Thomas Haller <thaller@redhat.com>
Kernel treats IPv6 route metrics with value zero (0) special.
Add a utility function that helps accounting for that.
Signed-off-by: Thomas Haller <thaller@redhat.com>
https://bugzilla.gnome.org/show_bug.cgi?id=738590
Deleting an IPv4 address using libnl requires the proper peer address.
Pass the address of the peer on to nm_platform_ip4_address_delete().
Signed-off-by: Thomas Haller <thaller@redhat.com>
This patch requires both upstream kernel support for
IFLA_INET6_ADDR_GEN_MODE which was merged in this patch:
ipv6: addrconf: implement address generation modes
bc91b0f07ada5535427373a4e2050877bcc12218
and corresponding libnl support, merged in these patches:
veth: add kernel header linux/veth.h for VETH defines
9dc6e6da90016a33929f262bea0187396e1a061b
link: update copy of kernel header include/linux/if_link.h
b51815a9dbd8e45fd2558bbe337fb360ca2fd861
link/inet6: add link IPv6 address generation mode support
558f966782539f6d975da705fd73cea561c9dc83
Change all DBUS_TYPE_G_UCHAR_ARRAY properties to G_TYPE_BYTES, and
update corresponding APIs. Notably, this means they are now refcounted
rather than being copied.
Update the rest of NM for the changes. The daemon still converts SSIDs
to GByteArrays internally, because changing it to use GBytes has lots
of trickle-down effects. It can possibly be changed later.
Previously, src/nm-ip4-config.h, libnm/nm-ip4-config.h, and
libnm-glib/nm-ip4-config.h all used "NM_IP4_CONFIG_H" as an include
guard, which meant that nm-test-utils.h could not tell which of them
was being included (and so, eg, if you tried to include
nm-ip4-config.h in a libnm test, it would fail to compile because
nm-test-utils.h was referring to symbols in src/nm-ip4-config.h).
Fix this by changing the include guards in the non-API-stable parts of
the tree:
- libnm-glib/nm-ip4-config.h remains NM_IP4_CONFIG_H
- libnm/nm-ip4-config.h now uses __NM_IP4_CONFIG_H__
- src/nm-ip4-config.h now uses __NETWORKMANAGER_IP4_CONFIG_H__
And likewise for all other headers.
The two non-"nm"-prefixed headers, libnm/NetworkManager.h and
src/NetworkManagerUtils.h are now __NETWORKMANAGER_H__ and
__NETWORKMANAGER_UTILS_H__ respectively, which, while not entirely
consistent with the general scheme, do still mostly make sense in
isolation.
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.
Lots of old code used struct ether_addr to store hardware addresses,
and ether_aton() to parse them, but more recent code generally uses
guint8 arrays, and the nm_utils_hwaddr_* methods, to be able to share
code between ETH_ALEN and INFINIBAND_ALEN cases. So update the old
code to match the new. (In many places, this ends up getting rid of
casts between struct ether_addr and guint8* anyway.)
(Also, in some places, variables were switched from struct ether_addr
to guint8[] a while back, but some code still used "&" when referring
to them even though that's unnecessary now. Clean that up.)
"NetworkManager.h"'s name (and non-standard capitalization) suggest
that it's some sort of high-level super-important header, but it's
really just low-level D-Bus stuff. Rename it to "nm-dbus-interface.h"
and likewise "NetworkManagerVPN.h" to "nm-vpn-dbus-interface.h"
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>
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.
When printing an address in nm_platform_ip4_address_to_string()
and nm_platform_ip6_address_to_string() treat an unset @timestamp
as counting from @now.
This is useful, if you just have the remaining lifetime at hand
and want to print an address. In general it is not a good idea to
leave the timestamp not anchored to an absolute @timestamp.
Signed-off-by: Thomas Haller <thaller@redhat.com>
Previous patch 8310a039d8 modified
platform to set the timestamp of addresses always to 1.
So, when adding an address platform logging looked like:
signal: address 4 added: 192.168.232.3/24 lft 2000sec pref 1000sec lifetime 12345-1[13344,14344] dev em1 src kernel
This is confusing in the log file and during debugging. Instead set the
timestamp to the last modification time of the address so that it will
look like:
signal: address 4 added: 192.168.232.3/24 lft 2000sec pref 1000sec lifetime 12345-12345[1000,2000] dev em1 src kernel
Signed-off-by: Thomas Haller <thaller@redhat.com>
The kernel tells the address lifetimes in the 'struct ifa_cacheinfo'
attribute. This contains two timestamps (cstamp and tstamp) and two
relative lifetimes (ifa_prefered and ifa_valid).
The timestamps are equal to clock_gettime(CLOCK_MONOTONIC) scale in
1/100th of a second (wrapping every 497 days).
The preferred/valid times are re-adjusted everytime when sending the
message and count down as the time goes by. In other words, they are
anchored relatively to the moment of when kernel creates the netlink
message.
As platform is caching the rtnl_addr object, the information of *when* the
lifetimes started counting is not available.
This patch fixes reading these values by hacking the libnl object
when it gets received, so that valid and preferred are instead absolute
expiration timestamps in scale nm_utils_get_monotonic_timestamp_s() --
which NM internally is used for address timestamps.
There are two minor downsides to this hack:
- the valid and preferred properties of a cached rtnl_addr object have
an unexpected meaning, i.e. they are absolute and in a different time
scale.
- later when converting rtnl_addr to NMPlatformIPAddress, the base
timestamp is set to "1", i.e. an NMPlatformIPAddress has no knowledge
of when the address was created or last modified. The timestamp
property of NMPlatformIPAddress is solely there to anchor the relative
timestamps lifetime and preferred. Do not use it for anything
else.
Another reason the timestamp property is meaningless is that
its scale nm_utils_get_monotonic_timestamp_s() starts counting at
process start. So addresses that existed before would have a negative
or zero timestamp, which we avoid. This in turn could be solved by either
allowing negative timestamps or by shifting
nm_utils_get_monotonic_timestamp_*(). Both is viable, but not
necessary (ATM), because the age of an address has no other apparent
use then to anchor the relative timestamps.
Another implication is, that we potentially could get rid of the
timestamp completely, and insteat make preferred and lifetime be
absolute expiries.
This will be fixed properly later, by not caching libnl objects but instead
native NMPlatform objects. For those we have full control over their properties.
https://bugzilla.gnome.org/show_bug.cgi?id=727382
Signed-off-by: Thomas Haller <thaller@redhat.com>
NMIP[46]Route had a "source" field, but it was always set to KERNEL
for routes read from the kernel (even if they were originally added by
NM).
Fix things a bit by translating between our "source" field and the
kernel's "protocol" field.
https://bugzilla.gnome.org/show_bug.cgi?id=729203
Add an additional address parameter to link_add/bridge_add, to set the
MAC address of software devices.
https://bugzilla.gnome.org/show_bug.cgi?id=729844
Signed-off-by: Thomas Haller <thaller@redhat.com>
This compares two addresses and returns which one has a longer
remaining life (i.e. a later expiry timestamp).
Signed-off-by: Thomas Haller <thaller@redhat.com>
Especially the calculation of timestamps is identicall for addresses.
By creating a "base struct", we can use the same code for that, because
NMPlatformIP4Address and NMPlatformIP6Address can now both be treated as
NMPlatformIPAddress (and the same for routes).
Signed-off-by: Thomas Haller <thaller@redhat.com>
Before platform raised 3 signals for each object type. Combine
them into one and add a new parameter @change_type to distinguish
between the change type.
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.
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.
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>
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>
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
The sysctl values in the kernel (for those values for which
nm_platform_sysctl_get_uint() is currently used) are defined as s32.
Change nm_platform_sysctl_get_uint() to nm_platform_sysctl_get_int32()
and ensure, that a matching integer type is used thoroughly.
Signed-off-by: Thomas Haller <thaller@redhat.com>
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.