"nm-dhcp-manager.h" forward declares _nm_dhcp_manager_factories.
We need to make the definition aware of the declaration, so
that the compiler can warn if they differ.
Replace the usage of g_str_hash() with our own nm_str_hash().
GLib's g_str_hash() uses djb2 hashing function, just like we
do at the moment. The only difference is, that we use a diffrent
seed value.
Note, that we initialize the hash seed with random data (by calling
getrandom() or reading /dev/urandom). That is a change compared to
before.
This change of the hashing function and accessing the random pool
might be undesired for libnm/libnm-core. Hence, the change is not
done there as it possibly changes behavior for public API. Maybe
we should do that later though.
At this point, there isn't much of a change. This patch becomes
interesting, if we decide to use a different hashing algorithm.
"nm-utils/nm-shared-utils.h" shall contain utility function without other
dependencies. It is intended to be used by other projects as-is.
nm_utils_random_bytes() requires getrandom() and a HAVE_GETRANDOM configure
check. That makes it more cumbersome to re-use "nm-shared-utils.h", in
cases where you don't care about nm_utils_random_bytes().
Split nm_utils_random_bytes() out to a separate file.
Same for hash utils, which depend on nm_utils_random_bytes(). Also, hash
utils will eventually be extended to use siphash24.
Instead of having 3 properties @gateway, @never_default and @has_gateway
on NMIP4Config/NMIP6Config that determine the default-route, track the
default-route as a regular route.
The gateway setting is the configuration knob for the default-route.
Since an NMIP4Config/NMIP6Config instance only has one gateway property,
it cannot track more then one default-routes (see related bug rh#1445417).
Especially with policy routing, it might be interesting to configure a
default-route in multiple tables.
Also, later it might be interesting to allow adding default-routes as
regular static routes in a connection, so that the user can configure additional
route parameters for the default-route or add default-routes in multiple tables.
With this patch, default-routes now have a rt_source property according to their
origin.
Also, the previous commits of this branch broke handling of the
default-route :) . That should be working now again.
The name "priority" is well established for routes (e.g. kernel's
RTA_PRIORITY netlink attribute).
However, we call it at most places "metric" or "route_metric".
Rename it, not to use two different names for the same thing.
Split out a separate function _method_call_handle(). That way we can get
rid of the "goto out" and use cleanup attribute to manage resources inside
_method_call_handle().
the --timeout command line option is a custom feature added in some
linux distributions (fedora). Passing that command line argument will
make dhclient fail if the binary does not support it, preventing
activation of dhcp based connections.
Worse, the option has just been recently changed from "-timeout", so
that we are currently incompatibile with Centos, RedHat and older
versions of Fedora too.
Leverage the "timeout" option in dhclient config file: it will produce
the expected behavior and will be universally supported.
Fixes test: dhcp-timeout
Fixes: fa46736013https://bugzilla.redhat.com/show_bug.cgi?id=1491243
In many cases we want to treat IPv4 and IPv6 generically. That looks nicer
if we distingish by an @addr_family integer, instead of a boolean.
Replace the @is_ipv6 boolean with an @addr_family paramter. The @is_ipv6
boolean is inconsistent with other places where we use @is_ipv4 to
indicate the opposite. Eventually, we should use @addr_family
everywhere.
Also, at the call site it's not immediately clear what TRUE/FALSE means,
here AF_INET/AF_INET6 is better.
- cleanup data type and use guint32 consistently. We might want to
introduce a new "infinity" value. But since libnm's
NM_SETTING_IP_CONFIG_DHCP_TIMEOUT asserts against the range
0 - G_MAXINT32, we cannot express it as -1 anyway. So, infinity
will have the numerical value G_MAXINT32, hence guint32 is just
fine.
- make use of existing ipv6.dhcp-timeout setting and add global
default configuration in NetworkManager.conf
- instead of having subclasses call nm_device_set_dhcp_timeout(),
add a virtual function get_dhcp_timeout().
A typo in the new dhcp-timeout option caused the dhclient daemon to exit
with error when the dhcp-timeout option was specified.
This prevents dhcp connection to be upped.
Fixes: 82ef497cc9
Kernel requires that the host part of a route (based on network/plen)
is zero. Routes with non-zero host part don't really exist.
In settings (NMIPRoute), we don't enforce that. Hence we must ensure
that we don't let such invalid routes into NMIP4Config/NMIP6Config.
Also at other places where we obtain routes from untrusted sources,
we must sanitize them first.
Also add an assertion to catch such bugs.
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.
In commit d405cfd908, parsing "interface"
statement is introduced. But it leads to uncommplete parsing of the
"request" entry, if one of the lines in "request" entry is prefixed with
word "interface". For example, the default configuration of openSUSE
distribution:
request subnet-mask, broadcast-address, routers,
rfc3442-classless-static-routes,
interface-mtu, host-name, domain-name, domain-search,
domain-name-servers, nis-domain, nis-servers,
nds-context, nds-servers, nds-tree-name,
netbios-name-servers, netbios-dd-server,
netbios-node-type, netbios-scope, ntp-servers;
Fixes: d405cfd908https://bugzilla.opensuse.org/show_bug.cgi?id=1047004https://mail.gnome.org/archives/networkmanager-list/2017-July/msg00015.html
Eventually, every NMPlatformIP4Route, NMPlatformIP6Route,
NMPlatformIP4Address and NMPlatformIP6Address should be shared
an deduplicated via the global NMDedupMultiIndex instance.
As first proof of concept, refactor NMIP4Config to track
IPv4 routes via the shared multi_idx. There is later potential
for improvement, when we pass (deduplicated) NMPObject instances
around instead of plain NMPlatformIP4Route, which needs still
a lot of comparing and cloning.
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.
lease_to_ip6_config() calls the GString temporary buffer "str".
That makes sense, use the same name in lease_to_ip4_config().
For that, we have to rename other local variables too.
rpmdiff complains about uses of inet_aton, inet_makeaddr, inet_netof,
inet_ntoa under the IPv6 section:
usr/sbin/NetworkManager on aarch64 i686 x86_64 ppc ppc64 ppc64le s390 s390x uses function inet_aton, which may impact IPv6 support
I think the warning is bogus, but refactor our code to avoid it.
Note that systemd code still uses them, so it don't avoid the rpmdiff
warning. But let's not diverge our systemd import from upstream for this.
- for NMSettingBond:validate_ip() also avoid g_strsplit_set() which
allocates a full strv. Instead, we can do with one g_strdup().
- for test-resolvconf-capture.c, replace the functions with macros.
Macros should be avoided usually, but for test asserts they are
more convenient as they preserved the __FILE__:__LINE__ of where
the assertion fails.
This basically reverts commit 31fe84e467 "core: Add host route for
DHCP4 server if outside assigned subnet (bgo #721767)" because the
additional route added by NM does more harm than good.
First, the code does not consider routes pushed by the server and thus
it can add a route conflicting with the ones from the network
administrator.
Second, there is no specification on what a DHCP client should do when
the server is not reachable via unicast, and adding arbitrary logic
into the client is likely to break things in specific cases. If
network administrators want to make the DHCP server reachable from a
client in a different subnet, they should push proper routes with the
lease.
In any case, if the DHCP server is not reachable through unicast,
before the lease expiration (after timeout T2) the client will resort
to broadcast and so there won't be any network disruption; the renewal
will only happen at a later time.
Fixes: 31fe84e467https://bugzilla.redhat.com/show_bug.cgi?id=1448987
If users wrote a FQDN in ipv4.dhcp-hostname presumably it's because
they really want to send the full value, not only the host part, so
let's send it as-is.
This obviously is a change in behavior, but only for users that have a
FQDN in ipv4.dhcp-hostname, where it's not clear if they really want the
domain to be stripped.
When the property is unset, we keep sending only the host part of the
system hostname to maintain backwards compatibility.
This commit aligns NM behavior to initscripts.
ISC dhclient will always append the zero label to the fqdn.fqdn option.
The dhcp-options(5) suggest that it's perfectly fine to have an
unqualified name.
"... This can be a fully-qualified domain name, or a single label. ..."
The ISC dhcpd will ignore this trailing zero label and do DDNS
regardless.
https://bugzilla.gnome.org/show_bug.cgi?id=761467
The default timeout in dhclient is 60 seconds; if a lease can't be
obtained during such interval, dhclient sends to NM a FAIL event and
then the IP method fails.
Thus, even if user specified a greater dhcp-timeout, NM terminated
DHCP after 60 seconds. Fix this by passing an explicit timeout to
dhclient.
It turns out that some routers return responses to DHCP6
Information-request messages that do not contain any of the options
that we insert in the "options" table. When that happened and the
info-only flag for DHCP6 was set, the assertion was triggered and
NetworkManager crashed. We remove the assertion as having empty options
is a possibility and is harmless anyway. This happened while using the
internal dhclient.
In practice, this should only matter when there are multiple
header files with the same name. That is something we try
to avoid already, by giving headers a distinct name.
When building NetworkManager itself, we clearly want to use
double-quotes for including our own headers.
But we also want to do that in our public headers. For example:
./a.c
#include <stdio.h>
#include <nm-1.h>
void main() {
printf ("INCLUDED %s/nm-2.h\n", SYMB);
}
./1/nm-1.h
#include <nm-2.h>
./1/nm-2.h
#define SYMB "1"
./2/nm-2.h
#define SYMB "2"
$ cc -I./2 -I./1 ./a.c
$ ./a.out
INCLUDED 2/nm-2.h
Exceptions to this are
- headers in "shared/nm-utils" that include <NetworkManager.h>. These
headers are copied into projects and hence used like headers owned by
those projects.
- examples/C
Until now any "interface" statement was ignored and any enclosed
statement for which we have a special handling was considered, even if
belonging to a different interface. This can cause wrong options to be
set in the generated dhclient configuration.
Change the code to parse "interface" statements and skip the content
if the interface doesn't match.
https://bugzilla.gnome.org/show_bug.cgi?id=778430
After commit 2049e97d9e ("dhcp: refactor parsing of 'request' and
'also request' options") NM parses all the existing 'request' and
'also request' from the original configuration file and appends them
as 'also request' to avoid duplicates and conflicts.
So if the original file contains 'request x' (which means "request
only option x instead of builtin defaults"), we would translate it
into 'also request x', which appends the option to the builtin
defaults, causing duplicates in the DHCP request as dhclient seems not
smart enough to sanitize the list by itself.
To fix this, ensure that the request list is reset if the
configuration file contains a 'request'.
Fixes: 2049e97d9ehttps://bugzilla.gnome.org/show_bug.cgi?id=778430
Also, ifnet plugin would read the configuration value, which is just wrong
because:
- the configuration might not be set and ifnet would fail to fallback
to the compile time default.
- the configuration only is in effect if the plugin is also available.
Otherwise, we fallback to the next plugin.
Only the dhcp-manager knows which DHCP plugin is in use.
Keep the include paths clean and separate. We use directories to group source
files together. That makes sense (I guess), but then we should use this
grouping also when including files. Thus require to #include files with their
path relative to "src/".
Also, we build various artifacts from the "src/" tree. Instead of having
individual CFLAGS for each artifact in Makefile.am, the CFLAGS should be
unified. Previously, the CFLAGS for each artifact differ and are inconsistent
in which paths they add to the search path. Fix the inconsistency by just
don't add the paths at all.