For addresses (NMPlatformIPAddress) the @addr_source field is ignored
on a platform level. That is, all addresses inside the platform cache
have this value set to NM_IP_CONFIG_SOURCE_KERNEL. Maybe, for that reason,
the source should not be a part of the NMPlatformIPAddress structure, but
it is convenient for users to piggy back the source inside the platform
address structure.
For routes, the source is stored in NMPlatformIPRoute's @rt_source
field. When adding a route to kernel, we set the @rtm_protocol of the
route depending on the source. However, we want to map different source
values to the same protocol value.
On the other hand, when kernel sends us a route that gets put inside
the cache, we must preserve the protocol value and must not map
different protocol values to the same source.
The reason is, that a user can add two routes that only differ by
@rtm_protocol. In that sense, the @rtm_protocol fields is part of the
unique ID of a kernel route, and thus different values must map to
different sources.
Fix this, by extending the range of NMIPConfigSource to contain
a range of protocol fields.
We handle cloned routes (that have rtm_flags RTM_F_CLONED) differently.
We used to mark such routes by hacking NMIPConfigSource to have a special
value. No longer do this, because it mixes different concepts.
Note that the rt_cloned filed fits into a hole in the aligment
of NMPlatformIPRoute. Thus there is almost no overhead to this
change.
The "source" field of NMPlatformIPRoute (now "rt_source") maps to the
protocol field of the route. The source of NMPlatformIPAddress (now
"addr_source") has no direct equivalent in the kernel.
As their use is different, they should have different names. Also,
the name "source" is used all over the place. Hence give the fields
a more distinct name.
For some device types, we use the DEVTYPE from sysfs to determine the
link type. However, the way we read from sysfs can race with device
renames and we could miss the chance to read DEVTYPE correctly.
This doesn't completely fix the sysfs race, but cures the boot-time race
with systemd renaming the device while we are initializing the link.
We ideally should use GUDev for all sysfs accesses, but that would need
some more work for this particular case as currently we need the link type
before we have an udev device instance.
https://bugzilla.gnome.org/show_bug.cgi?id=764803
Co-Authored-By: Beniamino Galvani <bgalvani@redhat.com>
wifi_utils_is_wifi() only has one caller, so it's very clear
what the passed in @sysfs_path contains. Instead of accepting
a redundant argument, compute the sysfs path internally based
on @iface alone.
Consider:
unshare -n
ip link add d0 type dummy
ip link add d1 type dummy
ip link set d0 up
ip link set d1 up
ip addr add 192.168.100.5/24 dev d0
ip addr add 192.168.101.5/24 dev d1
ip route add 192.168.200.0/24 via 192.168.100.1
ip monitor &
ip route change 192.168.200.0/24 via 192.168.101.1
#prints 192.168.200.0/24 via 192.168.101.1 dev d1
ip route show
#192.168.100.0/24 dev d0 proto kernel scope link src 192.168.100.5
#192.168.101.0/24 dev d1 proto kernel scope link src 192.168.101.5
#192.168.200.0/24 via 192.168.101.1 dev d1
Note that `ip route change` replaced the exising route. "Replaced" in this
case means: the previous route on device "d0" got removed and a new route
on "d1" was added. However, kernel only sent one RTM_NEWROUTE event, no
RTM_DELROUTE that notifies about this change.
We need to workaround that by re-synching the routes when we receive a
RTM_NEWROUTE notification.
We aim to keep the platform cache up-to-date only via the netlink
events. However, due to kernel shortcomings we often have to resync
by re-requesting the data, which especially for routes and addresses
means a full dump (as you cannot request only specific route/address
information).
Thus it makes sense to avoid expensive dumps whenever we can.
We schedule dumps via "delayed-actions" and that is already smart
so that muliple schedulings are combined. However, before requesting
a new dump, we clear the flag that indicates that a dump is scheduled.
Thus, while processing the result of of a dump, we would re-schedule
anew which can be necessary in some cases.
In certain cases, we don't require a full resync, when we are in the
middle of processing a dump, because that one dump will provide us
with the full picture. Thus, we can avoid scheduling a new dump if
- we already scheduled a delayed action
- we are in the middle or processing a dump.
This can now be checked via delayed_action_refresh_all_in_progress().
The link_stats structure grew between 4.5 and 4.6 and this would cause
the messages to me ignored when compiling with 4.6 headers and running
on 4.5.
https://bugzilla.gnome.org/show_bug.cgi?id=764332
str_if_set() was added to replace the non-standard gcc extension "?:".
However, "?:" is supported by clang as well and we already use it at
several places.
Also, str_if_set() did not follow our naming scheme and renaming to
nm_str_if_set() would be ugly. So just drop it.
Add a new NMPNetns class. This allows creation, deletion and
switching of network namespaces. The API only offers push/pop
operations to switch the namespace. This way the API enforces
the user to always restore the previous namespace.
A NMPlatform instance not only uses the netlink socket, but also
sysfs, udev, ethtool, mii. Still, a NMPlatform instance lives
entirely inside one namespace and is not spanning multiple namespaces.
To properly support network namespaces, the platform instance must
switch the namespace as necessary, transparent to the caller.
Udev is only supported in the main namespace.
For now, network namespaces are not actually used and are disabled
via the NM_PLATFORM_NETNS_SUPPORT argument.
https://bugzilla.gnome.org/show_bug.cgi?id=762408
Inside container, where we don't use udev we don't receive
any events from udev client. Thus the client only returns
devices when iterating it initially, but no events for newly
added devices that appear later.
Thus, inside containers we don't want to create a udev client
at all.
Most functions defined in "nm-platform-utils.h" perform a lookup
of link properties, for example via ethtool or sysfs. Those functions
depend on the system configuration, such as the current network namespace.
Move the simple helper functions away to "nm-core-internal.h", so that
all remaining functions from "nm-platform-utils.h" are really related to
somthing that interacts with the system/kernel.
Coverity complains rightly about "strncpy (dst, ifname, IFNAMSIZ)"
because it might leave @dst non-NULL-terminated, in case @ifname
is too long (which already would be a bug in the first place).
Replace the strcpy() uses by a new helper nm_utils_ifname_cpy()
that asserts against valid arguments.
It's useful to track the flags for IPv4 addresses too.
- we might want to sort IPv4 addresses according to whether they
are permanent or dynamic.
- later we want to set IFA_F_NOPREFIXROUTE also for IPv4 addresses.
While the ability to "set" a flag doesn't necessarily require that we
also keep the flags present in NMPlatformIP4Address, it is more consistent.
"NetworkManagerUtils.h" contains a bunch of helper tools for core
daemon ("src/").
Unfortunately, it has dependencies to other parts of core,
such as "nm-device.h" and "nm-platform.h". Split out a part
of tools that are independent so that they can be used without
dragging in other dependencies.
"nm-core-utils.h" should only use libnm-core, "nm-logging.h"
and shared.
"NetworkManagerUtils.h" should provide all "nm-core-utils.h" and
possibly other utilities that have larger dependencies.
"nm-logging.h" is a basic core module that should have few other
dependencies. Instead of letting nm-logging.c directly call a function
from "nm-linux-platform.c", let platform register a handler as needed.
This way, you can build a core library containing nm-logging but no
nm-platform.
There are far too many "flags". Rename the "flags" to "n_ifa_flags"
which reminds to "ifa_flags" in 'struct ifaddrmsg', but with a
distinctive "n_" prefix.
There are far too many "flags". Rename the "flags" to "n_ifi_flags"
which reminds to "ifi_flags" in 'struct ifinfomsg', but with a
distinctive "n_" prefix.
The value written to sysctl is usually a short string. It makes sense
to optimize for this case and avoid allocating a temporary string
on the heap.
An alternative would be to use writev(), which effectively does the same
and also creates a temporary buffer (preferably stack allocated).
https://mail.gnome.org/archives/networkmanager-list/2016-February/msg00070.html
- All internal source files (except "examples", which are not internal)
should include "config.h" first. As also all internal source
files should include "nm-default.h", let "config.h" be included
by "nm-default.h" and include "nm-default.h" as first in every
source file.
We already wanted to include "nm-default.h" before other headers
because it might contains some fixes (like "nm-glib.h" compatibility)
that is required first.
- After including "nm-default.h", we optinally allow for including the
corresponding header file for the source file at hand. The idea
is to ensure that each header file is self contained.
- Don't include "config.h" or "nm-default.h" in any header file
(except "nm-sd-adapt.h"). Public headers anyway must not include
these headers, and internal headers are never included after
"nm-default.h", as of the first previous point.
- Include all internal headers with quotes instead of angle brackets.
In practice it doesn't matter, because in our public headers we must
include other headers with angle brackets. As we use our public
headers also to compile our interal source files, effectively the
result must be the same. Still do it for consistency.
- Except for <config.h> itself. Include it with angle brackets as suggested by
https://www.gnu.org/software/autoconf/manual/autoconf.html#Configuration-Headers