2020-09-29 16:42:22 +02:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0+ */
|
2019-09-25 13:13:40 +02:00
|
|
|
/*
|
2017-11-23 15:41:57 +01:00
|
|
|
* Copyright (C) 2005 - 2017 Red Hat, Inc.
|
2008-11-03 04:13:42 +00:00
|
|
|
* Copyright (C) 2006 - 2008 Novell, Inc.
|
2005-04-15 15:43:42 +00:00
|
|
|
*/
|
|
|
|
|
|
2016-02-12 14:44:52 +01:00
|
|
|
#include "nm-default.h"
|
2016-02-19 14:57:48 +01:00
|
|
|
|
2016-02-12 14:44:52 +01:00
|
|
|
#include "nm-ip4-config.h"
|
|
|
|
|
|
2014-10-19 17:30:10 -04:00
|
|
|
#include <arpa/inet.h>
|
2017-10-06 13:17:58 +02:00
|
|
|
#include <resolv.h>
|
all: rework configuring route table support by adding "route-table" setting
We added "ipv4.route-table-sync" and "ipv6.route-table-sync" to not change
behavior for users that configured policy routing outside of NetworkManager,
for example, via a dispatcher script. Users had to explicitly opt-in
for NetworkManager to fully manage all routing tables.
These settings were awkward. Replace them with new settings "ipv4.route-table"
and "ipv6.route-table". Note that this commit breaks API/ABI on the unstable
development branch by removing recently added API.
As before, a connection will have no route-table set by default. This
has the meaning that policy-routing is not enabled and only the main table
will be fully synced. Once the user sets a table, we recognize that and
NetworkManager manages all routing tables.
The new route-table setting has other important uses: analog to
"ipv4.route-metric", it is the default that applies to all routes.
Currently it only works for static routes, not DHCP, SLAAC,
default-route, etc. That will be implemented later.
For static routes, each route still can explicitly set a table, and
overwrite the per-connection setting in "ipv4.route-table" and
"ipv6.route-table".
2017-09-28 08:40:41 +02:00
|
|
|
#include <linux/rtnetlink.h>
|
2013-07-12 11:33:52 +02:00
|
|
|
|
2019-04-15 08:16:00 +02:00
|
|
|
#include "nm-glib-aux/nm-dedup-multi.h"
|
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-06-12 08:16:47 +02:00
|
|
|
|
2008-06-02 08:44:48 +00:00
|
|
|
#include "nm-utils.h"
|
2017-06-12 18:40:14 +02:00
|
|
|
#include "platform/nmp-object.h"
|
2016-11-21 00:43:52 +01:00
|
|
|
#include "platform/nm-platform.h"
|
|
|
|
|
#include "platform/nm-platform-utils.h"
|
2013-11-19 22:28:36 -06:00
|
|
|
#include "NetworkManagerUtils.h"
|
2015-05-20 12:21:11 +02:00
|
|
|
#include "nm-core-internal.h"
|
core/dbus: rework D-Bus implementation to use lower layer GDBusConnection API
Previously, we used the generated GDBusInterfaceSkeleton types and glued
them via the NMExportedObject base class to our NM types. We also used
GDBusObjectManagerServer.
Don't do that anymore. The resulting code was more complicated despite (or
because?) using generated classes. It was hard to understand, complex, had
ordering-issues, and had a runtime and memory overhead.
This patch refactors this entirely and uses the lower layer API GDBusConnection
directly. It replaces the generated code, GDBusInterfaceSkeleton, and
GDBusObjectManagerServer. All this is now done by NMDbusObject and NMDBusManager
and static descriptor instances of type GDBusInterfaceInfo.
This adds a net plus of more then 1300 lines of hand written code. I claim
that this implementation is easier to understand. Note that previously we
also required extensive and complex glue code to bind our objects to the
generated skeleton objects. Instead, now glue our objects directly to
GDBusConnection. The result is more immediate and gets rid of layers of
code in between.
Now that the D-Bus glue us more under our control, we can address issus and
bottlenecks better, instead of adding code to bend the generated skeletons
to our needs.
Note that the current implementation now only supports one D-Bus connection.
That was effectively the case already, although there were places (and still are)
where the code pretends it could also support connections from a private socket.
We dropped private socket support mainly because it was unused, untested and
buggy, but also because GDBusObjectManagerServer could not export the same
objects on multiple connections. Now, it would be rather straight forward to
fix that and re-introduce ObjectManager on each private connection. But this
commit doesn't do that yet, and the new code intentionally supports only one
D-Bus connection.
Also, the D-Bus startup was simplified. There is no retry, either nm_dbus_manager_start()
succeeds, or it detects the initrd case. In the initrd case, bus manager never tries to
connect to D-Bus. Since the initrd scenario is not yet used/tested, this is good enough
for the moment. It could be easily extended later, for example with polling whether the
system bus appears (like was done previously). Also, restart of D-Bus daemon isn't
supported either -- just like before.
Note how NMDBusManager now implements the ObjectManager D-Bus interface
directly.
Also, this fixes race issues in the server, by no longer delaying
PropertiesChanged signals. NMExportedObject would collect changed
properties and send the signal out in idle_emit_properties_changed()
on idle. This messes up the ordering of change events w.r.t. other
signals and events on the bus. Note that not only NMExportedObject
messed up the ordering. Also the generated code would hook into
notify() and process change events in and idle handle, exhibiting the
same ordering issue too.
No longer do that. PropertiesChanged signals will be sent right away
by hooking into dispatch_properties_changed(). This means, changing
a property in quick succession will no longer be combined and is
guaranteed to emit signals for each individual state. Quite possibly
we emit now more PropertiesChanged signals then before.
However, we are now able to group a set of changes by using standard
g_object_freeze_notify()/g_object_thaw_notify(). We probably should
make more use of that.
Also, now that our signals are all handled in the right order, we
might find places where we still emit them in the wrong order. But that
is then due to the order in which our GObjects emit signals, not due
to an ill behavior of the D-Bus glue. Possibly we need to identify
such ordering issues and fix them.
Numbers (for contrib/rpm --without debug on x86_64):
- the patch changes the code size of NetworkManager by
- 2809360 bytes
+ 2537528 bytes (-9.7%)
- Runtime measurements are harder because there is a large variance
during testing. In other words, the numbers are not reproducible.
Currently, the implementation performs no caching of GVariants at all,
but it would be rather simple to add it, if that turns out to be
useful.
Anyway, without strong claim, it seems that the new form tends to
perform slightly better. That would be no surprise.
$ time (for i in {1..1000}; do nmcli >/dev/null || break; echo -n .; done)
- real 1m39.355s
+ real 1m37.432s
$ time (for i in {1..2000}; do busctl call org.freedesktop.NetworkManager /org/freedesktop org.freedesktop.DBus.ObjectManager GetManagedObjects > /dev/null || break; echo -n .; done)
- real 0m26.843s
+ real 0m25.281s
- Regarding RSS size, just looking at the processes in similar
conditions, doesn't give a large difference. On my system they
consume about 19MB RSS. It seems that the new version has a
slightly smaller RSS size.
- 19356 RSS
+ 18660 RSS
2018-02-26 13:51:52 +01:00
|
|
|
#include "nm-dbus-object.h"
|
2015-04-15 14:53:30 -04:00
|
|
|
|
2017-01-15 12:15:58 +01:00
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
/* internal guint32 are assigned to gobject properties of type uint. Ensure, that uint is large enough */
|
|
|
|
|
G_STATIC_ASSERT(sizeof(uint) >= sizeof(guint32));
|
|
|
|
|
G_STATIC_ASSERT(G_MAXUINT >= 0xFFFFFFFF);
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2017-07-19 11:30:13 +02:00
|
|
|
static gboolean
|
|
|
|
|
_route_valid(const NMPlatformIP4Route *r)
|
|
|
|
|
{
|
|
|
|
|
return r && r->plen <= 32
|
|
|
|
|
&& r->network == nm_utils_ip4_address_clear_host_address(r->network, r->plen);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2017-10-17 11:53:08 +02:00
|
|
|
static void
|
|
|
|
|
_idx_obj_id_hash_update(const NMDedupMultiIdxType *idx_type,
|
|
|
|
|
const NMDedupMultiObj * obj,
|
|
|
|
|
NMHashState * h)
|
2017-06-12 18:40:14 +02:00
|
|
|
{
|
2017-10-17 11:53:08 +02:00
|
|
|
nmp_object_id_hash_update((NMPObject *) obj, h);
|
2017-06-12 18:40:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
_idx_obj_id_equal(const NMDedupMultiIdxType *idx_type,
|
|
|
|
|
const NMDedupMultiObj * obj_a,
|
|
|
|
|
const NMDedupMultiObj * obj_b)
|
|
|
|
|
{
|
2017-09-11 21:41:57 +02:00
|
|
|
return nmp_object_id_equal((NMPObject *) obj_a, (NMPObject *) obj_b);
|
2017-06-12 18:40:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
nm_ip_config_dedup_multi_idx_type_init(NMIPConfigDedupMultiIdxType *idx_type,
|
|
|
|
|
NMPObjectType obj_type)
|
|
|
|
|
{
|
2017-09-11 21:41:57 +02:00
|
|
|
static const NMDedupMultiIdxTypeClass idx_type_class = {
|
2017-10-17 11:53:08 +02:00
|
|
|
.idx_obj_id_hash_update = _idx_obj_id_hash_update,
|
2017-09-11 21:41:57 +02:00
|
|
|
.idx_obj_id_equal = _idx_obj_id_equal,
|
|
|
|
|
};
|
|
|
|
|
|
2017-06-12 18:40:14 +02:00
|
|
|
nm_dedup_multi_idx_type_init((NMDedupMultiIdxType *) idx_type, &idx_type_class);
|
|
|
|
|
idx_type->obj_type = obj_type;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2017-07-07 23:34:41 +02:00
|
|
|
gboolean
|
|
|
|
|
_nm_ip_config_add_obj(NMDedupMultiIndex * multi_idx,
|
|
|
|
|
NMIPConfigDedupMultiIdxType *idx_type,
|
|
|
|
|
int ifindex,
|
|
|
|
|
const NMPObject * obj_new,
|
2017-08-16 14:38:39 +02:00
|
|
|
const NMPlatformObject * pl_new,
|
|
|
|
|
gboolean merge,
|
2017-08-30 19:05:38 +02:00
|
|
|
gboolean append_force,
|
2017-09-05 10:36:50 +02:00
|
|
|
const NMPObject ** out_obj_old /* returns a reference! */,
|
|
|
|
|
const NMPObject ** out_obj_new /* does not return a reference */)
|
2017-07-07 23:34:41 +02:00
|
|
|
{
|
|
|
|
|
NMPObject obj_new_stackinit;
|
|
|
|
|
const NMDedupMultiEntry *entry_old;
|
2017-08-30 19:05:38 +02:00
|
|
|
const NMDedupMultiEntry *entry_new;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-07-07 23:34:41 +02:00
|
|
|
nm_assert(multi_idx);
|
|
|
|
|
nm_assert(idx_type);
|
|
|
|
|
nm_assert(NM_IN_SET(idx_type->obj_type,
|
|
|
|
|
NMP_OBJECT_TYPE_IP4_ADDRESS,
|
|
|
|
|
NMP_OBJECT_TYPE_IP4_ROUTE,
|
|
|
|
|
NMP_OBJECT_TYPE_IP6_ADDRESS,
|
|
|
|
|
NMP_OBJECT_TYPE_IP6_ROUTE));
|
|
|
|
|
nm_assert(ifindex > 0);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-07-07 23:34:41 +02:00
|
|
|
/* we go through extra lengths to accept a full obj_new object. That one,
|
|
|
|
|
* can be reused by increasing the ref-count. */
|
|
|
|
|
if (!obj_new) {
|
|
|
|
|
nm_assert(pl_new);
|
|
|
|
|
obj_new = nmp_object_stackinit(&obj_new_stackinit, idx_type->obj_type, pl_new);
|
2019-03-04 13:01:21 +01:00
|
|
|
NMP_OBJECT_CAST_OBJ_WITH_IFINDEX(&obj_new_stackinit)->ifindex = ifindex;
|
2017-07-07 23:34:41 +02:00
|
|
|
} else {
|
|
|
|
|
nm_assert(!pl_new);
|
|
|
|
|
nm_assert(NMP_OBJECT_GET_TYPE(obj_new) == idx_type->obj_type);
|
2019-03-04 13:01:21 +01:00
|
|
|
if (NMP_OBJECT_CAST_OBJ_WITH_IFINDEX(obj_new)->ifindex != ifindex) {
|
2017-07-07 23:34:41 +02:00
|
|
|
obj_new = nmp_object_stackinit_obj(&obj_new_stackinit, obj_new);
|
2019-03-04 13:01:21 +01:00
|
|
|
NMP_OBJECT_CAST_OBJ_WITH_IFINDEX(&obj_new_stackinit)->ifindex = ifindex;
|
2017-07-07 23:34:41 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
nm_assert(NMP_OBJECT_GET_TYPE(obj_new) == idx_type->obj_type);
|
|
|
|
|
nm_assert(nmp_object_is_alive(obj_new));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-07-07 23:34:41 +02:00
|
|
|
entry_old = nm_dedup_multi_index_lookup_obj(multi_idx, &idx_type->parent, obj_new);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-07-07 23:34:41 +02:00
|
|
|
if (entry_old) {
|
|
|
|
|
gboolean modified = FALSE;
|
|
|
|
|
const NMPObject *obj_old = entry_old->obj;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-08-31 12:51:48 +02:00
|
|
|
if (nmp_object_equal(obj_new, obj_old)) {
|
|
|
|
|
nm_dedup_multi_entry_set_dirty(entry_old, FALSE);
|
2017-08-16 14:38:39 +02:00
|
|
|
goto append_force_and_out;
|
2017-08-31 12:51:48 +02:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-08-16 14:38:39 +02:00
|
|
|
/* if @merge, we merge the new object with the existing one.
|
|
|
|
|
* Otherwise, we replace it entirely. */
|
|
|
|
|
if (merge) {
|
|
|
|
|
switch (idx_type->obj_type) {
|
|
|
|
|
case NMP_OBJECT_TYPE_IP4_ADDRESS:
|
|
|
|
|
case NMP_OBJECT_TYPE_IP6_ADDRESS:
|
|
|
|
|
/* for addresses that we read from the kernel, we keep the timestamps as defined
|
|
|
|
|
* by the previous source (item_old). The reason is, that the other source configured the lifetimes
|
|
|
|
|
* with "what should be" and the kernel values are "what turned out after configuring it".
|
|
|
|
|
*
|
|
|
|
|
* For other sources, the longer lifetime wins. */
|
|
|
|
|
if ((obj_new->ip_address.addr_source == NM_IP_CONFIG_SOURCE_KERNEL
|
|
|
|
|
&& obj_old->ip_address.addr_source != NM_IP_CONFIG_SOURCE_KERNEL)
|
|
|
|
|
|| nm_platform_ip_address_cmp_expiry(NMP_OBJECT_CAST_IP_ADDRESS(obj_old),
|
|
|
|
|
NMP_OBJECT_CAST_IP_ADDRESS(obj_new))
|
|
|
|
|
> 0) {
|
|
|
|
|
obj_new = nmp_object_stackinit_obj(&obj_new_stackinit, obj_new);
|
|
|
|
|
obj_new_stackinit.ip_address.timestamp =
|
|
|
|
|
NMP_OBJECT_CAST_IP_ADDRESS(obj_old)->timestamp;
|
|
|
|
|
obj_new_stackinit.ip_address.lifetime =
|
|
|
|
|
NMP_OBJECT_CAST_IP_ADDRESS(obj_old)->lifetime;
|
|
|
|
|
obj_new_stackinit.ip_address.preferred =
|
|
|
|
|
NMP_OBJECT_CAST_IP_ADDRESS(obj_old)->preferred;
|
|
|
|
|
modified = TRUE;
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-09-12 13:24:52 +02:00
|
|
|
/* keep the maximum addr_source. */
|
|
|
|
|
if (obj_new->ip_address.addr_source < obj_old->ip_address.addr_source) {
|
|
|
|
|
obj_new = nmp_object_stackinit_obj(&obj_new_stackinit, obj_new);
|
|
|
|
|
obj_new_stackinit.ip_address.addr_source = obj_old->ip_address.addr_source;
|
|
|
|
|
modified = TRUE;
|
|
|
|
|
}
|
2017-08-16 14:38:39 +02:00
|
|
|
break;
|
|
|
|
|
case NMP_OBJECT_TYPE_IP4_ROUTE:
|
|
|
|
|
case NMP_OBJECT_TYPE_IP6_ROUTE:
|
2017-09-12 13:24:52 +02:00
|
|
|
/* keep the maximum rt_source. */
|
2017-08-16 14:38:39 +02:00
|
|
|
if (obj_new->ip_route.rt_source < obj_old->ip_route.rt_source) {
|
|
|
|
|
obj_new = nmp_object_stackinit_obj(&obj_new_stackinit, obj_new);
|
|
|
|
|
obj_new_stackinit.ip_route.rt_source = obj_old->ip_route.rt_source;
|
|
|
|
|
modified = TRUE;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
nm_assert_not_reached();
|
|
|
|
|
break;
|
2017-07-07 23:34:41 +02:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-08-31 12:51:48 +02:00
|
|
|
if (modified && nmp_object_equal(obj_new, obj_old)) {
|
|
|
|
|
nm_dedup_multi_entry_set_dirty(entry_old, FALSE);
|
2017-08-16 14:38:39 +02:00
|
|
|
goto append_force_and_out;
|
2017-07-07 23:34:41 +02:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-07 23:34:41 +02:00
|
|
|
if (!nm_dedup_multi_index_add_full(multi_idx,
|
|
|
|
|
&idx_type->parent,
|
|
|
|
|
obj_new,
|
2019-08-27 18:27:24 +02:00
|
|
|
append_force ? NM_DEDUP_MULTI_IDX_MODE_APPEND_FORCE
|
|
|
|
|
: NM_DEDUP_MULTI_IDX_MODE_APPEND,
|
2017-07-07 23:34:41 +02:00
|
|
|
NULL,
|
|
|
|
|
entry_old ?: NM_DEDUP_MULTI_ENTRY_MISSING,
|
|
|
|
|
NULL,
|
2017-08-30 19:05:38 +02:00
|
|
|
&entry_new,
|
2017-09-05 10:36:50 +02:00
|
|
|
out_obj_old)) {
|
2017-07-07 23:34:41 +02:00
|
|
|
nm_assert_not_reached();
|
2017-08-30 19:05:38 +02:00
|
|
|
NM_SET_OUT(out_obj_new, NULL);
|
2017-07-07 23:34:41 +02:00
|
|
|
return FALSE;
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-08-30 19:05:38 +02:00
|
|
|
NM_SET_OUT(out_obj_new, entry_new->obj);
|
2017-07-07 23:34:41 +02:00
|
|
|
return TRUE;
|
2017-08-16 14:38:39 +02:00
|
|
|
|
|
|
|
|
append_force_and_out:
|
2017-09-05 10:36:50 +02:00
|
|
|
NM_SET_OUT(out_obj_old, nmp_object_ref(entry_old->obj));
|
2017-08-30 19:05:38 +02:00
|
|
|
NM_SET_OUT(out_obj_new, entry_old->obj);
|
2017-08-16 14:38:39 +02:00
|
|
|
if (append_force) {
|
|
|
|
|
if (nm_dedup_multi_entry_reorder(entry_old, NULL, TRUE))
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
return FALSE;
|
2017-07-07 23:34:41 +02:00
|
|
|
}
|
|
|
|
|
|
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-14 14:18:53 +02:00
|
|
|
/**
|
|
|
|
|
* _nm_ip_config_lookup_ip_route:
|
|
|
|
|
* @multi_idx:
|
|
|
|
|
* @idx_type:
|
|
|
|
|
* @needle:
|
|
|
|
|
* @cmp_type: after lookup, filter the result by comparing with @cmp_type. Only
|
|
|
|
|
* return the result, if it compares equal to @needle according to this @cmp_type.
|
|
|
|
|
* Note that the index uses %NM_PLATFORM_IP_ROUTE_CMP_TYPE_DST type, so passing
|
|
|
|
|
* that compare-type means not to filter any further.
|
|
|
|
|
*
|
|
|
|
|
* Returns: the found entry or %NULL.
|
|
|
|
|
*/
|
|
|
|
|
const NMDedupMultiEntry *
|
|
|
|
|
_nm_ip_config_lookup_ip_route(const NMDedupMultiIndex * multi_idx,
|
|
|
|
|
const NMIPConfigDedupMultiIdxType *idx_type,
|
|
|
|
|
const NMPObject * needle,
|
|
|
|
|
NMPlatformIPRouteCmpType cmp_type)
|
|
|
|
|
{
|
|
|
|
|
const NMDedupMultiEntry *entry;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
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-14 14:18:53 +02:00
|
|
|
nm_assert(multi_idx);
|
|
|
|
|
nm_assert(idx_type);
|
|
|
|
|
nm_assert(NM_IN_SET(idx_type->obj_type, NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE));
|
|
|
|
|
nm_assert(NMP_OBJECT_GET_TYPE(needle) == idx_type->obj_type);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
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-14 14:18:53 +02:00
|
|
|
entry = nm_dedup_multi_index_lookup_obj(multi_idx, &idx_type->parent, needle);
|
|
|
|
|
if (!entry)
|
|
|
|
|
return NULL;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-09-19 09:40:13 +02:00
|
|
|
if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID) {
|
|
|
|
|
nm_assert((NMP_OBJECT_GET_TYPE(needle) == NMP_OBJECT_TYPE_IP4_ROUTE
|
|
|
|
|
&& nm_platform_ip4_route_cmp(NMP_OBJECT_CAST_IP4_ROUTE(entry->obj),
|
|
|
|
|
NMP_OBJECT_CAST_IP4_ROUTE(needle),
|
|
|
|
|
cmp_type)
|
|
|
|
|
== 0)
|
|
|
|
|
|| (NMP_OBJECT_GET_TYPE(needle) == NMP_OBJECT_TYPE_IP6_ROUTE
|
|
|
|
|
&& nm_platform_ip6_route_cmp(NMP_OBJECT_CAST_IP6_ROUTE(entry->obj),
|
|
|
|
|
NMP_OBJECT_CAST_IP6_ROUTE(needle),
|
|
|
|
|
cmp_type)
|
|
|
|
|
== 0));
|
|
|
|
|
} else {
|
|
|
|
|
if (NMP_OBJECT_GET_TYPE(needle) == NMP_OBJECT_TYPE_IP4_ROUTE) {
|
|
|
|
|
if (nm_platform_ip4_route_cmp(NMP_OBJECT_CAST_IP4_ROUTE(entry->obj),
|
|
|
|
|
NMP_OBJECT_CAST_IP4_ROUTE(needle),
|
|
|
|
|
cmp_type)
|
|
|
|
|
!= 0)
|
|
|
|
|
return NULL;
|
|
|
|
|
} else {
|
|
|
|
|
if (nm_platform_ip6_route_cmp(NMP_OBJECT_CAST_IP6_ROUTE(entry->obj),
|
|
|
|
|
NMP_OBJECT_CAST_IP6_ROUTE(needle),
|
|
|
|
|
cmp_type)
|
|
|
|
|
!= 0)
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
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-14 14:18:53 +02:00
|
|
|
}
|
|
|
|
|
return entry;
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-07 23:34:41 +02:00
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2017-01-15 12:15:58 +01:00
|
|
|
NM_GOBJECT_PROPERTIES_DEFINE(NMIP4Config,
|
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-06-12 08:16:47 +02:00
|
|
|
PROP_MULTI_IDX,
|
2017-01-15 12:15:58 +01:00
|
|
|
PROP_IFINDEX,
|
|
|
|
|
PROP_ADDRESS_DATA,
|
|
|
|
|
PROP_ADDRESSES,
|
|
|
|
|
PROP_ROUTE_DATA,
|
|
|
|
|
PROP_ROUTES,
|
|
|
|
|
PROP_GATEWAY,
|
all: avoid byte ordering issue for IP4Config's Nameservers/WinsServers on D-Bus
Some properties in NetworkManager's D-Bus API are IPv4 addresses
in network byte order (big endian). That is problematic.
It is no problem, when the NetworkManager client runs on the same
host. That is the case with libnm, which does not support to be used
remotely for the time being.
It is a problem for an application that wants to access the D-Bus
interface of NetworkManager remotely. Possibly, such an application
would be implemented in two layers:
- one layer merely remotes D-Bus, without specific knowledge of
NetworkManager's API.
- a higher layer which accesses the remote D-Bus interface of NetworkManager.
Preferably it does so in an agnostic way, regardless of whether it runs
locally or remotely.
When using a D-Bus library, all accesses to 32 bit integers are in
native endianness (regardless of how the integer is actually encoded
on the lower layers). Likewise, D-Bus does not support annotating integer
types in non-native endianness. There is no way to annotate an integer
type "u" to be anything but native order.
That means, when remoting D-Bus at some point the endianness must be
corrected.
But by looking at the D-Bus introspection alone, it is not possible
to know which property need correction and which don't. One would need
to understand the meaning of the properties.
That makes it problematic, because the higher layer of the application,
which knows that the "Nameservers" property is supposed to be in network
order, might not easily know, whether it must correct for endianness.
Deprecate IP4Config properties that are only accessible with a particular
endianness, and add new properties that expose the same data in an
agnostic way.
Note that I added "WinsServerData" to be a plain "as", while
"NameserverData" is of type "aa{sv}". There is no particularly strong
reason for these choices, except that I could imagine that it could be
useful to expose additional information in the future about nameservers
(e.g. are they received via DHCP or manual configuration?). On the other
hand, WINS information likely won't get extended in the future.
Also note, libnm was not modified to use the new D-Bus fields. The
endianness issue is no problem for libnm, so there is little reason to
change it (at this point).
https://bugzilla.redhat.com/show_bug.cgi?id=1153559
https://bugzilla.redhat.com/show_bug.cgi?id=1584584
2018-07-13 20:15:33 +02:00
|
|
|
PROP_NAMESERVER_DATA,
|
2017-01-15 12:15:58 +01:00
|
|
|
PROP_NAMESERVERS,
|
|
|
|
|
PROP_DOMAINS,
|
|
|
|
|
PROP_SEARCHES,
|
|
|
|
|
PROP_DNS_OPTIONS,
|
all: avoid byte ordering issue for IP4Config's Nameservers/WinsServers on D-Bus
Some properties in NetworkManager's D-Bus API are IPv4 addresses
in network byte order (big endian). That is problematic.
It is no problem, when the NetworkManager client runs on the same
host. That is the case with libnm, which does not support to be used
remotely for the time being.
It is a problem for an application that wants to access the D-Bus
interface of NetworkManager remotely. Possibly, such an application
would be implemented in two layers:
- one layer merely remotes D-Bus, without specific knowledge of
NetworkManager's API.
- a higher layer which accesses the remote D-Bus interface of NetworkManager.
Preferably it does so in an agnostic way, regardless of whether it runs
locally or remotely.
When using a D-Bus library, all accesses to 32 bit integers are in
native endianness (regardless of how the integer is actually encoded
on the lower layers). Likewise, D-Bus does not support annotating integer
types in non-native endianness. There is no way to annotate an integer
type "u" to be anything but native order.
That means, when remoting D-Bus at some point the endianness must be
corrected.
But by looking at the D-Bus introspection alone, it is not possible
to know which property need correction and which don't. One would need
to understand the meaning of the properties.
That makes it problematic, because the higher layer of the application,
which knows that the "Nameservers" property is supposed to be in network
order, might not easily know, whether it must correct for endianness.
Deprecate IP4Config properties that are only accessible with a particular
endianness, and add new properties that expose the same data in an
agnostic way.
Note that I added "WinsServerData" to be a plain "as", while
"NameserverData" is of type "aa{sv}". There is no particularly strong
reason for these choices, except that I could imagine that it could be
useful to expose additional information in the future about nameservers
(e.g. are they received via DHCP or manual configuration?). On the other
hand, WINS information likely won't get extended in the future.
Also note, libnm was not modified to use the new D-Bus fields. The
endianness issue is no problem for libnm, so there is little reason to
change it (at this point).
https://bugzilla.redhat.com/show_bug.cgi?id=1153559
https://bugzilla.redhat.com/show_bug.cgi?id=1584584
2018-07-13 20:15:33 +02:00
|
|
|
PROP_WINS_SERVER_DATA,
|
2017-01-15 12:15:58 +01:00
|
|
|
PROP_WINS_SERVERS,
|
|
|
|
|
PROP_DNS_PRIORITY, );
|
|
|
|
|
|
2016-05-11 11:41:54 +02:00
|
|
|
typedef struct {
|
2017-01-15 12:33:10 +01:00
|
|
|
bool metered : 1;
|
2020-09-29 12:06:11 +02:00
|
|
|
bool never_default : 1;
|
2017-01-15 12:33:10 +01:00
|
|
|
guint32 mtu;
|
|
|
|
|
int ifindex;
|
|
|
|
|
NMIPConfigSource mtu_source;
|
all: don't use gchar/gshort/gint/glong but C types
We commonly don't use the glib typedefs for char/short/int/long,
but their C types directly.
$ git grep '\<g\(char\|short\|int\|long\|float\|double\)\>' | wc -l
587
$ git grep '\<\(char\|short\|int\|long\|float\|double\)\>' | wc -l
21114
One could argue that using the glib typedefs is preferable in
public API (of our glib based libnm library) or where it clearly
is related to glib, like during
g_object_set (obj, PROPERTY, (gint) value, NULL);
However, that argument does not seem strong, because in practice we don't
follow that argument today, and seldomly use the glib typedefs.
Also, the style guide for this would be hard to formalize, because
"using them where clearly related to a glib" is a very loose suggestion.
Also note that glib typedefs will always just be typedefs of the
underlying C types. There is no danger of glib changing the meaning
of these typedefs (because that would be a major API break of glib).
A simple style guide is instead: don't use these typedefs.
No manual actions, I only ran the bash script:
FILES=($(git ls-files '*.[hc]'))
sed -i \
-e 's/\<g\(char\|short\|int\|long\|float\|double\)\>\( [^ ]\)/\1\2/g' \
-e 's/\<g\(char\|short\|int\|long\|float\|double\)\> /\1 /g' \
-e 's/\<g\(char\|short\|int\|long\|float\|double\)\>/\1/g' \
"${FILES[@]}"
2018-07-11 07:40:19 +02:00
|
|
|
int dns_priority;
|
core: implement setting MDNS setting for systemd
The connection.mdns setting is a per-connection setting,
so one might expect that one activated device can only have
one MDNS setting at a time.
However, with certain VPN plugins (those that don't have their
own IP interface, like libreswan), the VPN configuration is merged
into the configuration of the device. So, in this case, there
might be multiple settings for one device that must be merged.
We already have a mechanism for that. It's NMIP4Config. Let NMIP4Config
track this piece of information. Although, stricitly speaking this
is not tied to IPv4, the alternative would be to introduce a new
object to track such data, which would be a tremendous effort
and more complicated then this.
Luckily, NMDnsManager and NMDnsPlugin are already equipped to
handle multiple NMIPConfig instances per device (IPv4 vs. IPv6,
and Device vs. VPN).
Also make "connection.mdns" configurable via global defaults in
NetworkManager.conf.
2017-12-20 14:49:32 +01:00
|
|
|
NMSettingConnectionMdns mdns;
|
2018-08-31 15:14:39 +02:00
|
|
|
NMSettingConnectionLlmnr llmnr;
|
2007-02-16 11:23:49 +00:00
|
|
|
GArray * nameservers;
|
|
|
|
|
GPtrArray * domains;
|
2008-03-09 05:11:22 +00:00
|
|
|
GPtrArray * searches;
|
2015-03-26 09:23:12 +01:00
|
|
|
GPtrArray * dns_options;
|
2010-07-16 11:28:39 -07:00
|
|
|
GArray * nis;
|
2013-07-12 11:33:52 +02:00
|
|
|
char * nis_domain;
|
|
|
|
|
GArray * wins;
|
2016-11-18 11:52:38 +01:00
|
|
|
GVariant * address_data_variant;
|
|
|
|
|
GVariant * addresses_variant;
|
2017-07-11 13:20:23 +02:00
|
|
|
GVariant * route_data_variant;
|
|
|
|
|
GVariant * routes_variant;
|
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-06-12 08:16:47 +02:00
|
|
|
NMDedupMultiIndex * multi_idx;
|
2017-08-31 13:39:04 +02:00
|
|
|
const NMPObject * best_default_route;
|
2017-07-07 23:34:41 +02:00
|
|
|
union {
|
|
|
|
|
NMIPConfigDedupMultiIdxType idx_ip4_addresses_;
|
|
|
|
|
NMDedupMultiIdxType idx_ip4_addresses;
|
|
|
|
|
};
|
2017-07-10 21:53:24 +02:00
|
|
|
union {
|
|
|
|
|
NMIPConfigDedupMultiIdxType idx_ip4_routes_;
|
|
|
|
|
NMDedupMultiIdxType idx_ip4_routes;
|
|
|
|
|
};
|
2020-04-22 10:35:16 +02:00
|
|
|
NMIPConfigFlags config_flags;
|
2007-02-16 11:23:49 +00:00
|
|
|
} NMIP4ConfigPrivate;
|
|
|
|
|
|
2016-05-11 11:41:54 +02:00
|
|
|
struct _NMIP4Config {
|
2020-07-29 19:30:22 +02:00
|
|
|
NMIPConfig parent;
|
2016-05-11 11:41:54 +02:00
|
|
|
NMIP4ConfigPrivate _priv;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct _NMIP4ConfigClass {
|
2020-07-29 19:30:22 +02:00
|
|
|
NMIPConfigClass parent;
|
2016-05-11 11:41:54 +02:00
|
|
|
};
|
|
|
|
|
|
2020-07-29 19:30:22 +02:00
|
|
|
G_DEFINE_TYPE(NMIP4Config, nm_ip4_config, NM_TYPE_IP_CONFIG)
|
2016-05-11 11:41:54 +02:00
|
|
|
|
2016-09-05 16:55:07 +02:00
|
|
|
#define NM_IP4_CONFIG_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMIP4Config, NM_IS_IP4_CONFIG)
|
2016-05-11 11:41:54 +02:00
|
|
|
|
2017-01-15 12:15:58 +01:00
|
|
|
/*****************************************************************************/
|
2013-07-12 11:33:52 +02:00
|
|
|
|
2017-07-07 23:34:41 +02:00
|
|
|
static void
|
|
|
|
|
_add_address(NMIP4Config *self, const NMPObject *obj_new, const NMPlatformIP4Address *new);
|
2017-09-05 10:36:50 +02:00
|
|
|
static void _add_route(NMIP4Config * self,
|
|
|
|
|
const NMPObject *obj_new,
|
|
|
|
|
const NMPlatformIP4Route *new,
|
|
|
|
|
const NMPObject **out_obj_new);
|
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-14 14:18:53 +02:00
|
|
|
static const NMDedupMultiEntry *
|
2017-09-05 10:36:50 +02:00
|
|
|
_lookup_route(const NMIP4Config *self, const NMPObject *needle, NMPlatformIPRouteCmpType cmp_type);
|
2017-06-12 18:40:14 +02:00
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2015-02-27 16:49:42 +01:00
|
|
|
int
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_get_ifindex(const NMIP4Config *self)
|
2015-02-27 16:49:42 +01:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
return NM_IP4_CONFIG_GET_PRIVATE(self)->ifindex;
|
2015-02-27 16:49:42 +01:00
|
|
|
}
|
|
|
|
|
|
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-06-12 08:16:47 +02:00
|
|
|
NMDedupMultiIndex *
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_get_multi_idx(const NMIP4Config *self)
|
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-06-12 08:16:47 +02:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
return NM_IP4_CONFIG_GET_PRIVATE(self)->multi_idx;
|
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-06-12 08:16:47 +02:00
|
|
|
}
|
|
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2015-10-22 15:15:47 +02:00
|
|
|
|
2017-07-07 23:34:41 +02:00
|
|
|
const NMDedupMultiHeadEntry *
|
|
|
|
|
nm_ip4_config_lookup_addresses(const NMIP4Config *self)
|
2017-06-12 18:40:14 +02:00
|
|
|
{
|
|
|
|
|
const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
|
|
|
|
|
|
|
|
|
return nm_dedup_multi_index_lookup_head(priv->multi_idx, &priv->idx_ip4_addresses, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-07 23:34:41 +02:00
|
|
|
void
|
|
|
|
|
nm_ip_config_iter_ip4_address_init(NMDedupMultiIter *ipconf_iter, const NMIP4Config *self)
|
2017-06-12 18:40:14 +02:00
|
|
|
{
|
2017-07-07 23:34:41 +02:00
|
|
|
g_return_if_fail(NM_IS_IP4_CONFIG(self));
|
|
|
|
|
nm_dedup_multi_iter_init(ipconf_iter, nm_ip4_config_lookup_addresses(self));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2017-06-12 18:40:14 +02:00
|
|
|
|
2017-07-07 23:34:41 +02:00
|
|
|
const NMDedupMultiHeadEntry *
|
|
|
|
|
nm_ip4_config_lookup_routes(const NMIP4Config *self)
|
|
|
|
|
{
|
|
|
|
|
const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
|
|
|
|
|
|
|
|
|
return nm_dedup_multi_index_lookup_head(priv->multi_idx, &priv->idx_ip4_routes, NULL);
|
2017-06-12 18:40:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2017-07-07 23:34:41 +02:00
|
|
|
nm_ip_config_iter_ip4_route_init(NMDedupMultiIter *ipconf_iter, const NMIP4Config *self)
|
2017-06-12 18:40:14 +02:00
|
|
|
{
|
2020-08-12 14:01:21 +02:00
|
|
|
nm_assert(NM_IS_IP4_CONFIG(self));
|
2017-07-07 23:34:41 +02:00
|
|
|
nm_dedup_multi_iter_init(ipconf_iter, nm_ip4_config_lookup_routes(self));
|
2017-06-12 18:40:14 +02:00
|
|
|
}
|
|
|
|
|
|
2017-07-07 23:34:41 +02:00
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2017-08-31 13:39:04 +02:00
|
|
|
const NMPObject *
|
|
|
|
|
_nm_ip_config_best_default_route_find_better(const NMPObject *obj_cur, const NMPObject *obj_cmp)
|
|
|
|
|
{
|
|
|
|
|
nm_assert(!obj_cur
|
|
|
|
|
|| NM_IN_SET(NMP_OBJECT_GET_TYPE(obj_cur),
|
|
|
|
|
NMP_OBJECT_TYPE_IP4_ROUTE,
|
|
|
|
|
NMP_OBJECT_TYPE_IP6_ROUTE));
|
|
|
|
|
nm_assert(!obj_cmp
|
|
|
|
|
|| (!obj_cur
|
|
|
|
|
&& NM_IN_SET(NMP_OBJECT_GET_TYPE(obj_cmp),
|
|
|
|
|
NMP_OBJECT_TYPE_IP4_ROUTE,
|
|
|
|
|
NMP_OBJECT_TYPE_IP6_ROUTE))
|
|
|
|
|
|| NMP_OBJECT_GET_TYPE(obj_cur) == NMP_OBJECT_GET_TYPE(obj_cmp));
|
2020-07-21 18:30:23 +02:00
|
|
|
nm_assert(!obj_cur || nmp_object_ip_route_is_best_defaut_route(obj_cur));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-08-31 13:39:04 +02:00
|
|
|
/* assumes that @obj_cur is already the best default route (or NULL). It checks whether
|
|
|
|
|
* @obj_cmp is also a default route and returns the best of both. */
|
2020-07-21 18:30:23 +02:00
|
|
|
if (obj_cmp && nmp_object_ip_route_is_best_defaut_route(obj_cmp)) {
|
2020-07-03 15:25:51 +02:00
|
|
|
guint32 metric_cur, metric_cmp;
|
|
|
|
|
|
2017-08-31 13:39:04 +02:00
|
|
|
if (!obj_cur)
|
|
|
|
|
return obj_cmp;
|
|
|
|
|
|
2020-07-03 15:25:51 +02:00
|
|
|
metric_cur = NMP_OBJECT_CAST_IP_ROUTE(obj_cur)->metric;
|
|
|
|
|
metric_cmp = NMP_OBJECT_CAST_IP_ROUTE(obj_cmp)->metric;
|
2017-08-31 13:39:04 +02:00
|
|
|
|
|
|
|
|
if (metric_cmp < metric_cur)
|
|
|
|
|
return obj_cmp;
|
|
|
|
|
|
|
|
|
|
if (metric_cmp == metric_cur) {
|
2020-07-03 15:25:51 +02:00
|
|
|
int c;
|
|
|
|
|
|
2017-08-31 13:39:04 +02:00
|
|
|
/* Routes have the same metric. We still want to deterministically
|
|
|
|
|
* prefer one or the other. It's important to consistently choose one
|
|
|
|
|
* or the other, so that the order doesn't matter how routes are added
|
|
|
|
|
* (and merged). */
|
|
|
|
|
c = nmp_object_cmp(obj_cur, obj_cmp);
|
|
|
|
|
if (c != 0)
|
|
|
|
|
return c < 0 ? obj_cur : obj_cmp;
|
|
|
|
|
|
|
|
|
|
/* as last resort, compare pointers. */
|
|
|
|
|
if (obj_cmp < obj_cur)
|
|
|
|
|
return obj_cmp;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return obj_cur;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
|
_nm_ip_config_best_default_route_merge(const NMPObject **best_default_route,
|
|
|
|
|
const NMPObject * new_candidate)
|
|
|
|
|
{
|
|
|
|
|
new_candidate =
|
|
|
|
|
_nm_ip_config_best_default_route_find_better(*best_default_route, new_candidate);
|
2020-07-21 17:49:23 +02:00
|
|
|
return nmp_object_ref_set(best_default_route, new_candidate);
|
2017-08-31 13:39:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const NMPObject *
|
|
|
|
|
nm_ip4_config_best_default_route_get(const NMIP4Config *self)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail(NM_IS_IP4_CONFIG(self), NULL);
|
|
|
|
|
|
|
|
|
|
return NM_IP4_CONFIG_GET_PRIVATE(self)->best_default_route;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const NMPObject *
|
|
|
|
|
_nm_ip4_config_best_default_route_find(const NMIP4Config *self)
|
|
|
|
|
{
|
|
|
|
|
NMDedupMultiIter ipconf_iter;
|
|
|
|
|
const NMPObject *new_best_default_route = NULL;
|
|
|
|
|
|
|
|
|
|
nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, self, NULL) {
|
|
|
|
|
new_best_default_route =
|
|
|
|
|
_nm_ip_config_best_default_route_find_better(new_best_default_route,
|
|
|
|
|
ipconf_iter.current->obj);
|
|
|
|
|
}
|
|
|
|
|
return new_best_default_route;
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-04 15:21:21 +02:00
|
|
|
in_addr_t
|
|
|
|
|
nmtst_ip4_config_get_gateway(NMIP4Config *config)
|
|
|
|
|
{
|
|
|
|
|
const NMPObject *rt;
|
|
|
|
|
|
|
|
|
|
g_assert(NM_IS_IP4_CONFIG(config));
|
|
|
|
|
|
|
|
|
|
rt = nm_ip4_config_best_default_route_get(config);
|
|
|
|
|
if (!rt)
|
|
|
|
|
return 0;
|
|
|
|
|
return NMP_OBJECT_CAST_IP4_ROUTE(rt)->gateway;
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-31 13:39:04 +02:00
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2017-07-07 23:34:41 +02:00
|
|
|
static void
|
|
|
|
|
_notify_addresses(NMIP4Config *self)
|
2017-06-12 18:40:14 +02:00
|
|
|
{
|
2017-07-07 23:34:41 +02:00
|
|
|
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2017-06-12 18:40:14 +02:00
|
|
|
|
2017-07-07 23:34:41 +02:00
|
|
|
nm_clear_g_variant(&priv->address_data_variant);
|
|
|
|
|
nm_clear_g_variant(&priv->addresses_variant);
|
core: use nm_gobject_notify_together() in NMIP4Config/NMIP6Config
nm_gobject_notify_together() freezes the notifications to emit both
notification signals together. That matters for NMDBusObject base
class, which hooks into dispatch_properties_changed() to emit a combined
"PropertiesChanged" signal.
Note, that during calls like nm_ip4_config_replace(), we already
froze/thawed the notifications. So, this change adds unnecessary
freeze/thaw calls, because signal emition is already frozen.
That is a bit ugly, because g_object_freeze_notify() is more heavy
than I'd wish it would be.
Anyway, for other places, like nm_ip4_config_reset_routes() that is
not the case. And correctness trumps performance.
Ultimately, the issue there is that we use NMIP4Config / NMIP6Config
both to track internal configuration, and to expose it on D-Bus.
The majority of created NMIP4Config / NMIP6Config instances won't get
exported, and but still pay an unnecessary overhead. The proper solution
to minimize the overhead would be, to separate these uses.
2018-07-14 17:18:58 +02:00
|
|
|
nm_gobject_notify_together(self, PROP_ADDRESS_DATA, PROP_ADDRESSES);
|
2017-07-07 23:34:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
_notify_routes(NMIP4Config *self)
|
|
|
|
|
{
|
2017-07-11 13:20:23 +02:00
|
|
|
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
|
|
|
|
|
2017-08-31 13:39:04 +02:00
|
|
|
nm_assert(priv->best_default_route == _nm_ip4_config_best_default_route_find(self));
|
2017-07-11 13:20:23 +02:00
|
|
|
nm_clear_g_variant(&priv->route_data_variant);
|
|
|
|
|
nm_clear_g_variant(&priv->routes_variant);
|
core: use nm_gobject_notify_together() in NMIP4Config/NMIP6Config
nm_gobject_notify_together() freezes the notifications to emit both
notification signals together. That matters for NMDBusObject base
class, which hooks into dispatch_properties_changed() to emit a combined
"PropertiesChanged" signal.
Note, that during calls like nm_ip4_config_replace(), we already
froze/thawed the notifications. So, this change adds unnecessary
freeze/thaw calls, because signal emition is already frozen.
That is a bit ugly, because g_object_freeze_notify() is more heavy
than I'd wish it would be.
Anyway, for other places, like nm_ip4_config_reset_routes() that is
not the case. And correctness trumps performance.
Ultimately, the issue there is that we use NMIP4Config / NMIP6Config
both to track internal configuration, and to expose it on D-Bus.
The majority of created NMIP4Config / NMIP6Config instances won't get
exported, and but still pay an unnecessary overhead. The proper solution
to minimize the overhead would be, to separate these uses.
2018-07-14 17:18:58 +02:00
|
|
|
nm_gobject_notify_together(self, PROP_ROUTE_DATA, PROP_ROUTES);
|
2017-06-12 18:40:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2017-07-07 23:34:41 +02:00
|
|
|
static int
|
|
|
|
|
sort_captured_addresses(const CList *lst_a, const CList *lst_b, gconstpointer user_data)
|
2017-06-13 14:44:22 +02:00
|
|
|
{
|
2017-07-07 23:34:41 +02:00
|
|
|
const NMPlatformIP4Address *addr_a =
|
|
|
|
|
NMP_OBJECT_CAST_IP4_ADDRESS(c_list_entry(lst_a, NMDedupMultiEntry, lst_entries)->obj);
|
|
|
|
|
const NMPlatformIP4Address *addr_b =
|
|
|
|
|
NMP_OBJECT_CAST_IP4_ADDRESS(c_list_entry(lst_b, NMDedupMultiEntry, lst_entries)->obj);
|
2017-06-13 14:44:22 +02:00
|
|
|
|
2019-08-02 09:01:32 +02:00
|
|
|
nm_assert(addr_a);
|
|
|
|
|
nm_assert(addr_b);
|
|
|
|
|
|
2017-06-13 14:44:22 +02:00
|
|
|
/* Primary addresses first */
|
|
|
|
|
return NM_FLAGS_HAS(addr_a->n_ifa_flags, IFA_F_SECONDARY)
|
|
|
|
|
- NM_FLAGS_HAS(addr_b->n_ifa_flags, IFA_F_SECONDARY);
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-20 11:36:47 +01:00
|
|
|
NMIP4Config *
|
|
|
|
|
nm_ip4_config_clone(const NMIP4Config *self)
|
|
|
|
|
{
|
|
|
|
|
NMIP4Config *copy;
|
|
|
|
|
|
|
|
|
|
copy = nm_ip4_config_new(nm_ip4_config_get_multi_idx(self), -1);
|
|
|
|
|
nm_ip4_config_replace(copy, self, NULL);
|
|
|
|
|
|
|
|
|
|
return copy;
|
|
|
|
|
}
|
|
|
|
|
|
2013-04-04 10:20:24 -04:00
|
|
|
NMIP4Config *
|
2018-03-09 18:43:53 +01:00
|
|
|
nm_ip4_config_capture(NMDedupMultiIndex *multi_idx, NMPlatform *platform, int ifindex)
|
2013-04-04 10:20:24 -04:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
NMIP4Config * self;
|
2013-11-06 14:13:59 -06:00
|
|
|
NMIP4ConfigPrivate * priv;
|
2017-07-07 23:34:41 +02:00
|
|
|
const NMDedupMultiHeadEntry *head_entry;
|
2017-06-29 15:19:35 +02:00
|
|
|
NMDedupMultiIter iter;
|
|
|
|
|
const NMPObject * plobj = NULL;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-07-07 23:34:41 +02:00
|
|
|
nm_assert(ifindex > 0);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-11-06 14:13:59 -06:00
|
|
|
/* Slaves have no IP configuration */
|
2017-04-17 20:17:45 +02:00
|
|
|
if (nm_platform_link_get_master(platform, ifindex) > 0)
|
2013-11-06 14:13:59 -06:00
|
|
|
return NULL;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-07-10 14:03:44 +02:00
|
|
|
self = nm_ip4_config_new(multi_idx, ifindex);
|
|
|
|
|
priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-11-23 15:41:57 +01:00
|
|
|
head_entry = nm_platform_lookup_object(platform, NMP_OBJECT_TYPE_IP4_ADDRESS, ifindex);
|
2017-07-07 23:34:41 +02:00
|
|
|
if (head_entry) {
|
|
|
|
|
nmp_cache_iter_for_each (&iter, head_entry, &plobj) {
|
2017-08-30 14:05:16 +02:00
|
|
|
if (!_nm_ip_config_add_obj(priv->multi_idx,
|
|
|
|
|
&priv->idx_ip4_addresses_,
|
|
|
|
|
ifindex,
|
|
|
|
|
plobj,
|
|
|
|
|
NULL,
|
|
|
|
|
FALSE,
|
2017-08-30 19:05:38 +02:00
|
|
|
TRUE,
|
2017-09-05 10:36:50 +02:00
|
|
|
NULL,
|
2017-08-30 19:05:38 +02:00
|
|
|
NULL))
|
2017-07-07 23:34:41 +02:00
|
|
|
nm_assert_not_reached();
|
|
|
|
|
}
|
|
|
|
|
head_entry = nm_ip4_config_lookup_addresses(self);
|
|
|
|
|
nm_assert(head_entry);
|
|
|
|
|
nm_dedup_multi_head_entry_sort(head_entry, sort_captured_addresses, NULL);
|
2017-10-04 15:21:21 +02:00
|
|
|
_notify_addresses(self);
|
2017-07-07 23:34:41 +02:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-11-23 15:41:57 +01:00
|
|
|
head_entry = nm_platform_lookup_object(platform, NMP_OBJECT_TYPE_IP4_ROUTE, ifindex);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-11-02 09:44:47 -05:00
|
|
|
/* Extract gateway from default route */
|
2017-10-04 15:21:21 +02:00
|
|
|
nmp_cache_iter_for_each (&iter, head_entry, &plobj)
|
2017-09-05 10:36:50 +02:00
|
|
|
_add_route(self, plobj, NULL, NULL);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-07-10 14:03:44 +02:00
|
|
|
return self;
|
2013-04-04 10:20:24 -04:00
|
|
|
}
|
|
|
|
|
|
2018-07-21 10:42:04 +02:00
|
|
|
void
|
|
|
|
|
nm_ip4_config_update_routes_metric(NMIP4Config *self, gint64 metric)
|
|
|
|
|
{
|
|
|
|
|
gs_free NMPlatformIP4Route *routes = NULL;
|
|
|
|
|
gboolean need_update = FALSE;
|
|
|
|
|
const NMPlatformIP4Route * r;
|
|
|
|
|
NMDedupMultiIter iter;
|
|
|
|
|
guint num = 0, i = 0;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2018-07-21 10:42:04 +02:00
|
|
|
nm_ip_config_iter_ip4_route_for_each (&iter, self, &r) {
|
|
|
|
|
if (r->metric != metric)
|
|
|
|
|
need_update = TRUE;
|
|
|
|
|
num++;
|
|
|
|
|
}
|
|
|
|
|
if (!need_update)
|
|
|
|
|
return;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2018-07-21 10:42:04 +02:00
|
|
|
routes = g_new(NMPlatformIP4Route, num);
|
|
|
|
|
nm_ip_config_iter_ip4_route_for_each (&iter, self, &r) {
|
|
|
|
|
routes[i] = *r;
|
|
|
|
|
routes[i].metric = metric;
|
|
|
|
|
i++;
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2018-07-21 10:42:04 +02:00
|
|
|
g_object_freeze_notify(G_OBJECT(self));
|
|
|
|
|
nm_ip4_config_reset_routes(self);
|
|
|
|
|
for (i = 0; i < num; i++)
|
|
|
|
|
nm_ip4_config_add_route(self, &routes[i], NULL);
|
|
|
|
|
g_object_thaw_notify(G_OBJECT(self));
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-12 13:45:53 +02:00
|
|
|
void
|
2017-10-04 15:21:21 +02:00
|
|
|
nm_ip4_config_add_dependent_routes(NMIP4Config *self,
|
2020-07-14 11:35:35 +02:00
|
|
|
guint32 route_table,
|
|
|
|
|
guint32 route_metric,
|
|
|
|
|
gboolean is_vrf,
|
|
|
|
|
GPtrArray ** out_ip4_dev_route_blacklist)
|
2013-07-03 10:26:19 +02:00
|
|
|
{
|
2017-09-12 13:45:53 +02:00
|
|
|
GPtrArray * ip4_dev_route_blacklist = NULL;
|
2017-10-04 15:21:21 +02:00
|
|
|
const NMPlatformIP4Address *my_addr;
|
|
|
|
|
const NMPlatformIP4Route * my_route;
|
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-14 14:18:53 +02:00
|
|
|
int ifindex;
|
2017-09-12 13:45:53 +02:00
|
|
|
NMDedupMultiIter iter;
|
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-14 14:18:53 +02:00
|
|
|
|
2017-09-12 13:45:53 +02:00
|
|
|
g_return_if_fail(NM_IS_IP4_CONFIG(self));
|
2013-07-03 10:26:19 +02:00
|
|
|
|
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-14 14:18:53 +02:00
|
|
|
ifindex = nm_ip4_config_get_ifindex(self);
|
2017-09-12 13:45:53 +02:00
|
|
|
g_return_if_fail(ifindex > 0);
|
2013-07-03 10:26:19 +02:00
|
|
|
|
2017-09-19 09:40:13 +02:00
|
|
|
/* For IPv6 slaac, we explicitly add the device-routes (onlink) to NMIP6Config.
|
|
|
|
|
* As we don't do that for IPv4 (and manual IPv6 addresses), add them explicitly. */
|
2017-07-07 23:34:41 +02:00
|
|
|
|
2017-10-04 15:21:21 +02:00
|
|
|
nm_ip_config_iter_ip4_address_for_each (&iter, self, &my_addr) {
|
2017-09-12 13:45:53 +02:00
|
|
|
nm_auto_nmpobj NMPObject *r = NULL;
|
|
|
|
|
NMPlatformIP4Route * route;
|
|
|
|
|
in_addr_t network;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-10-04 15:21:21 +02:00
|
|
|
if (my_addr->plen == 0)
|
2017-09-12 13:45:53 +02:00
|
|
|
continue;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-10-04 15:21:21 +02:00
|
|
|
nm_assert(my_addr->plen <= 32);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-09-12 13:45:53 +02:00
|
|
|
/* The destination network depends on the peer-address. */
|
2017-10-04 15:21:21 +02:00
|
|
|
network = nm_utils_ip4_address_clear_host_address(my_addr->peer_address, my_addr->plen);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2019-10-17 11:36:38 +02:00
|
|
|
if (my_addr->external)
|
|
|
|
|
continue;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-07-27 16:28:02 +02:00
|
|
|
/* Pre-generate local route added by kernel */
|
|
|
|
|
r = nmp_object_new(NMP_OBJECT_TYPE_IP4_ROUTE, NULL);
|
|
|
|
|
route = NMP_OBJECT_CAST_IP4_ROUTE(r);
|
|
|
|
|
route->ifindex = ifindex;
|
|
|
|
|
route->rt_source = NM_IP_CONFIG_SOURCE_KERNEL;
|
|
|
|
|
route->network = my_addr->address;
|
|
|
|
|
route->plen = 32;
|
|
|
|
|
route->pref_src = my_addr->address;
|
|
|
|
|
route->type_coerced = nm_platform_route_type_coerce(RTN_LOCAL);
|
|
|
|
|
route->scope_inv = nm_platform_route_scope_inv(RT_SCOPE_HOST);
|
|
|
|
|
route->table_coerced =
|
|
|
|
|
nm_platform_route_table_coerce(is_vrf ? route_table : RT_TABLE_LOCAL);
|
|
|
|
|
_add_route(self, r, NULL, NULL);
|
|
|
|
|
nm_clear_pointer(&r, nmp_object_unref);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-07-28 09:16:37 +02:00
|
|
|
if (nm_utils_ip4_address_is_zeronet(network)) {
|
2017-09-12 13:45:53 +02:00
|
|
|
/* Kernel doesn't add device-routes for destinations that
|
|
|
|
|
* start with 0.x.y.z. Skip them. */
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-23 21:52:48 +02:00
|
|
|
if (my_addr->plen == 32 && my_addr->address == my_addr->peer_address) {
|
|
|
|
|
/* Kernel doesn't add device-routes for /32 addresses unless
|
|
|
|
|
* they have a peer. */
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-09-12 13:45:53 +02:00
|
|
|
r = nmp_object_new(NMP_OBJECT_TYPE_IP4_ROUTE, NULL);
|
|
|
|
|
route = NMP_OBJECT_CAST_IP4_ROUTE(r);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-09-12 13:45:53 +02:00
|
|
|
route->ifindex = ifindex;
|
|
|
|
|
route->rt_source = NM_IP_CONFIG_SOURCE_KERNEL;
|
|
|
|
|
route->network = network;
|
2017-10-04 15:21:21 +02:00
|
|
|
route->plen = my_addr->plen;
|
|
|
|
|
route->pref_src = my_addr->address;
|
2017-09-28 14:40:12 +02:00
|
|
|
route->table_coerced = nm_platform_route_table_coerce(route_table);
|
all: rework configuring route table support by adding "route-table" setting
We added "ipv4.route-table-sync" and "ipv6.route-table-sync" to not change
behavior for users that configured policy routing outside of NetworkManager,
for example, via a dispatcher script. Users had to explicitly opt-in
for NetworkManager to fully manage all routing tables.
These settings were awkward. Replace them with new settings "ipv4.route-table"
and "ipv6.route-table". Note that this commit breaks API/ABI on the unstable
development branch by removing recently added API.
As before, a connection will have no route-table set by default. This
has the meaning that policy-routing is not enabled and only the main table
will be fully synced. Once the user sets a table, we recognize that and
NetworkManager manages all routing tables.
The new route-table setting has other important uses: analog to
"ipv4.route-metric", it is the default that applies to all routes.
Currently it only works for static routes, not DHCP, SLAAC,
default-route, etc. That will be implemented later.
For static routes, each route still can explicitly set a table, and
overwrite the per-connection setting in "ipv4.route-table" and
"ipv6.route-table".
2017-09-28 08:40:41 +02:00
|
|
|
route->metric = route_metric;
|
2017-09-12 13:45:53 +02:00
|
|
|
route->scope_inv = nm_platform_route_scope_inv(NM_RT_SCOPE_LINK);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-09-12 13:45:53 +02:00
|
|
|
nm_platform_ip_route_normalize(AF_INET, (NMPlatformIPRoute *) route);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-09-12 13:45:53 +02:00
|
|
|
if (_lookup_route(self, r, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID)) {
|
|
|
|
|
/* we already track this route. Don't add it again. */
|
|
|
|
|
} else
|
2017-10-10 09:52:39 +02:00
|
|
|
_add_route(self, r, NULL, NULL);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-09-12 13:45:53 +02:00
|
|
|
if (out_ip4_dev_route_blacklist
|
2017-09-28 14:40:12 +02:00
|
|
|
&& (route_table != RT_TABLE_MAIN
|
|
|
|
|
|| route_metric != NM_PLATFORM_ROUTE_METRIC_IP4_DEVICE_ROUTE)) {
|
2017-09-12 13:45:53 +02:00
|
|
|
nm_auto_nmpobj NMPObject *r_dev = NULL;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-09-12 13:45:53 +02:00
|
|
|
r_dev = nmp_object_clone(r, FALSE);
|
|
|
|
|
route = NMP_OBJECT_CAST_IP4_ROUTE(r_dev);
|
2017-09-28 14:40:12 +02:00
|
|
|
route->table_coerced = nm_platform_route_table_coerce(RT_TABLE_MAIN);
|
2017-09-12 13:45:53 +02:00
|
|
|
route->metric = NM_PLATFORM_ROUTE_METRIC_IP4_DEVICE_ROUTE;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
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-14 14:18:53 +02:00
|
|
|
nm_platform_ip_route_normalize(AF_INET, (NMPlatformIPRoute *) route);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
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-14 14:18:53 +02:00
|
|
|
if (_lookup_route(self, r_dev, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID)) {
|
2017-09-12 13:45:53 +02:00
|
|
|
/* we track such a route explicitly. Don't blacklist it. */
|
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-14 14:18:53 +02:00
|
|
|
} else {
|
2017-09-12 13:45:53 +02:00
|
|
|
if (!ip4_dev_route_blacklist)
|
|
|
|
|
ip4_dev_route_blacklist =
|
|
|
|
|
g_ptr_array_new_with_free_func((GDestroyNotify) nmp_object_unref);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-09-12 13:45:53 +02:00
|
|
|
g_ptr_array_add(ip4_dev_route_blacklist, g_steal_pointer(&r_dev));
|
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-14 14:18:53 +02:00
|
|
|
}
|
2017-09-12 13:45:53 +02:00
|
|
|
}
|
|
|
|
|
}
|
2017-08-14 14:24:39 +02:00
|
|
|
|
2017-10-04 15:21:21 +02:00
|
|
|
again:
|
|
|
|
|
nm_ip_config_iter_ip4_route_for_each (&iter, self, &my_route) {
|
|
|
|
|
NMPlatformIP4Route rt;
|
|
|
|
|
|
|
|
|
|
if (!NM_PLATFORM_IP_ROUTE_IS_DEFAULT(my_route) || my_route->gateway == 0
|
|
|
|
|
|| NM_IS_IP_CONFIG_SOURCE_RTPROT(my_route->rt_source)
|
|
|
|
|
|| nm_ip4_config_get_direct_route_for_host(
|
|
|
|
|
self,
|
|
|
|
|
my_route->gateway,
|
|
|
|
|
nm_platform_route_table_uncoerce(my_route->table_coerced, TRUE)))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
rt = *my_route;
|
|
|
|
|
rt.network = my_route->gateway;
|
|
|
|
|
rt.plen = 32;
|
|
|
|
|
rt.gateway = 0;
|
|
|
|
|
_add_route(self, NULL, &rt, NULL);
|
|
|
|
|
/* adding the route might have invalidated the iteration. Start again. */
|
|
|
|
|
goto again;
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-12 13:45:53 +02:00
|
|
|
NM_SET_OUT(out_ip4_dev_route_blacklist, ip4_dev_route_blacklist);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
|
nm_ip4_config_commit(const NMIP4Config * self,
|
2017-09-13 17:42:41 +02:00
|
|
|
NMPlatform * platform,
|
|
|
|
|
NMIPRouteTableSyncMode route_table_sync)
|
2017-09-12 13:45:53 +02:00
|
|
|
{
|
|
|
|
|
gs_unref_ptrarray GPtrArray *addresses = NULL;
|
|
|
|
|
gs_unref_ptrarray GPtrArray *routes = NULL;
|
core: inject route list to delete for nm_platform_ip_route_sync()
Whenever we call a platform operation that reads or writes the netlink
socket, there is the possibility that the cache gets updated, as we
receive netlink events.
It is thus racy, if nm_platform_ip_route_sync() *first* adds routes, and
then obtains a list of routes to delete. The correct approach is to
determine which routes to delete first (and keep it in a list
@routes_prune), and pass that list down to nm_platform_ip_route_sync().
Arguably, this doesn't yet solve every race. For example, NMDevice
calls update_ext_ip_config() during ip4_config_merge_and_apply().
That is good, as it resyncs with platform. However, before calling
nm_ip4_config_commit() it calls other platform operations, like
_commit_mtu(). So, the race is still there.
2017-09-22 12:37:12 +02:00
|
|
|
gs_unref_ptrarray GPtrArray *routes_prune = NULL;
|
2017-09-12 13:45:53 +02:00
|
|
|
int ifindex;
|
|
|
|
|
gboolean success = TRUE;
|
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-14 14:18:53 +02:00
|
|
|
|
2017-09-12 13:45:53 +02:00
|
|
|
g_return_val_if_fail(NM_IS_IP4_CONFIG(self), FALSE);
|
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-14 14:18:53 +02:00
|
|
|
|
2017-09-12 13:45:53 +02:00
|
|
|
ifindex = nm_ip4_config_get_ifindex(self);
|
|
|
|
|
g_return_val_if_fail(ifindex > 0, FALSE);
|
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-14 14:18:53 +02:00
|
|
|
|
2017-09-12 13:45:53 +02:00
|
|
|
addresses =
|
|
|
|
|
nm_dedup_multi_objs_to_ptr_array_head(nm_ip4_config_lookup_addresses(self), NULL, NULL);
|
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-14 14:18:53 +02:00
|
|
|
|
2017-09-12 13:45:53 +02:00
|
|
|
routes = nm_dedup_multi_objs_to_ptr_array_head(nm_ip4_config_lookup_routes(self), NULL, NULL);
|
2013-07-03 10:26:19 +02:00
|
|
|
|
core: inject route list to delete for nm_platform_ip_route_sync()
Whenever we call a platform operation that reads or writes the netlink
socket, there is the possibility that the cache gets updated, as we
receive netlink events.
It is thus racy, if nm_platform_ip_route_sync() *first* adds routes, and
then obtains a list of routes to delete. The correct approach is to
determine which routes to delete first (and keep it in a list
@routes_prune), and pass that list down to nm_platform_ip_route_sync().
Arguably, this doesn't yet solve every race. For example, NMDevice
calls update_ext_ip_config() during ip4_config_merge_and_apply().
That is good, as it resyncs with platform. However, before calling
nm_ip4_config_commit() it calls other platform operations, like
_commit_mtu(). So, the race is still there.
2017-09-22 12:37:12 +02:00
|
|
|
routes_prune =
|
|
|
|
|
nm_platform_ip_route_get_prune_list(platform, AF_INET, ifindex, route_table_sync);
|
|
|
|
|
|
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-14 14:18:53 +02:00
|
|
|
nm_platform_ip4_address_sync(platform, ifindex, addresses);
|
2013-07-03 10:26:19 +02:00
|
|
|
|
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-14 14:18:53 +02:00
|
|
|
if (!nm_platform_ip_route_sync(platform, AF_INET, ifindex, routes, routes_prune, NULL))
|
|
|
|
|
success = FALSE;
|
2017-08-14 14:24:39 +02:00
|
|
|
|
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-14 14:18:53 +02:00
|
|
|
return success;
|
2013-07-03 10:26:19 +02:00
|
|
|
}
|
|
|
|
|
|
2008-09-05 02:55:40 +00:00
|
|
|
void
|
all: rework configuring route table support by adding "route-table" setting
We added "ipv4.route-table-sync" and "ipv6.route-table-sync" to not change
behavior for users that configured policy routing outside of NetworkManager,
for example, via a dispatcher script. Users had to explicitly opt-in
for NetworkManager to fully manage all routing tables.
These settings were awkward. Replace them with new settings "ipv4.route-table"
and "ipv6.route-table". Note that this commit breaks API/ABI on the unstable
development branch by removing recently added API.
As before, a connection will have no route-table set by default. This
has the meaning that policy-routing is not enabled and only the main table
will be fully synced. Once the user sets a table, we recognize that and
NetworkManager manages all routing tables.
The new route-table setting has other important uses: analog to
"ipv4.route-metric", it is the default that applies to all routes.
Currently it only works for static routes, not DHCP, SLAAC,
default-route, etc. That will be implemented later.
For static routes, each route still can explicitly set a table, and
overwrite the per-connection setting in "ipv4.route-table" and
"ipv6.route-table".
2017-09-28 08:40:41 +02:00
|
|
|
nm_ip4_config_merge_setting(NMIP4Config * self,
|
|
|
|
|
NMSettingIPConfig * setting,
|
core: implement setting MDNS setting for systemd
The connection.mdns setting is a per-connection setting,
so one might expect that one activated device can only have
one MDNS setting at a time.
However, with certain VPN plugins (those that don't have their
own IP interface, like libreswan), the VPN configuration is merged
into the configuration of the device. So, in this case, there
might be multiple settings for one device that must be merged.
We already have a mechanism for that. It's NMIP4Config. Let NMIP4Config
track this piece of information. Although, stricitly speaking this
is not tied to IPv4, the alternative would be to introduce a new
object to track such data, which would be a tremendous effort
and more complicated then this.
Luckily, NMDnsManager and NMDnsPlugin are already equipped to
handle multiple NMIPConfig instances per device (IPv4 vs. IPv6,
and Device vs. VPN).
Also make "connection.mdns" configurable via global defaults in
NetworkManager.conf.
2017-12-20 14:49:32 +01:00
|
|
|
NMSettingConnectionMdns mdns,
|
2018-08-31 15:14:39 +02:00
|
|
|
NMSettingConnectionLlmnr llmnr,
|
all: rework configuring route table support by adding "route-table" setting
We added "ipv4.route-table-sync" and "ipv6.route-table-sync" to not change
behavior for users that configured policy routing outside of NetworkManager,
for example, via a dispatcher script. Users had to explicitly opt-in
for NetworkManager to fully manage all routing tables.
These settings were awkward. Replace them with new settings "ipv4.route-table"
and "ipv6.route-table". Note that this commit breaks API/ABI on the unstable
development branch by removing recently added API.
As before, a connection will have no route-table set by default. This
has the meaning that policy-routing is not enabled and only the main table
will be fully synced. Once the user sets a table, we recognize that and
NetworkManager manages all routing tables.
The new route-table setting has other important uses: analog to
"ipv4.route-metric", it is the default that applies to all routes.
Currently it only works for static routes, not DHCP, SLAAC,
default-route, etc. That will be implemented later.
For static routes, each route still can explicitly set a table, and
overwrite the per-connection setting in "ipv4.route-table" and
"ipv6.route-table".
2017-09-28 08:40:41 +02:00
|
|
|
guint32 route_table,
|
|
|
|
|
guint32 route_metric)
|
2008-09-05 02:55:40 +00:00
|
|
|
{
|
2013-07-12 11:33:52 +02:00
|
|
|
guint naddresses, nroutes, nnameservers, nsearches;
|
2016-04-23 15:57:14 +02:00
|
|
|
int i, priority;
|
2017-10-04 15:21:21 +02:00
|
|
|
const char *gateway_str;
|
|
|
|
|
guint32 gateway_bin;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-07-03 10:26:19 +02:00
|
|
|
if (!setting)
|
2013-07-12 11:33:52 +02:00
|
|
|
return;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2014-10-19 17:30:10 -04:00
|
|
|
g_return_if_fail(NM_IS_SETTING_IP4_CONFIG(setting));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-07-10 14:03:44 +02:00
|
|
|
g_object_freeze_notify(G_OBJECT(self));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2014-10-19 17:30:10 -04:00
|
|
|
naddresses = nm_setting_ip_config_get_num_addresses(setting);
|
|
|
|
|
nroutes = nm_setting_ip_config_get_num_routes(setting);
|
|
|
|
|
nnameservers = nm_setting_ip_config_get_num_dns(setting);
|
|
|
|
|
nsearches = nm_setting_ip_config_get_num_dns_searches(setting);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-07-12 11:33:52 +02:00
|
|
|
/* Gateway */
|
2017-10-04 15:21:21 +02:00
|
|
|
if (!nm_setting_ip_config_get_never_default(setting)
|
|
|
|
|
&& (gateway_str = nm_setting_ip_config_get_gateway(setting))
|
|
|
|
|
&& inet_pton(AF_INET, gateway_str, &gateway_bin) == 1 && gateway_bin) {
|
|
|
|
|
const NMPlatformIP4Route r = {
|
|
|
|
|
.rt_source = NM_IP_CONFIG_SOURCE_USER,
|
|
|
|
|
.gateway = gateway_bin,
|
|
|
|
|
.table_coerced = nm_platform_route_table_coerce(route_table),
|
|
|
|
|
.metric = route_metric,
|
|
|
|
|
};
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-10-04 15:21:21 +02:00
|
|
|
_add_route(self, NULL, &r, NULL);
|
2013-07-03 10:26:19 +02:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-07-12 11:33:52 +02:00
|
|
|
/* Addresses */
|
2013-06-29 13:33:36 +02:00
|
|
|
for (i = 0; i < naddresses; i++) {
|
2014-10-19 17:30:10 -04:00
|
|
|
NMIPAddress * s_addr = nm_setting_ip_config_get_address(setting, i);
|
2014-09-16 16:38:04 -04:00
|
|
|
GVariant * label;
|
2013-06-29 13:33:36 +02:00
|
|
|
NMPlatformIP4Address address;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-06-29 13:33:36 +02:00
|
|
|
memset(&address, 0, sizeof(address));
|
2014-09-16 16:42:46 -04:00
|
|
|
nm_ip_address_get_address_binary(s_addr, &address.address);
|
2015-10-21 23:17:11 +02:00
|
|
|
address.peer_address = address.address;
|
2014-09-16 16:42:46 -04:00
|
|
|
address.plen = nm_ip_address_get_prefix(s_addr);
|
2016-04-06 18:04:26 +02:00
|
|
|
nm_assert(address.plen <= 32);
|
2013-07-04 20:40:18 +02:00
|
|
|
address.lifetime = NM_PLATFORM_LIFETIME_PERMANENT;
|
|
|
|
|
address.preferred = NM_PLATFORM_LIFETIME_PERMANENT;
|
2016-04-11 13:09:52 +02:00
|
|
|
address.addr_source = NM_IP_CONFIG_SOURCE_USER;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-12-11 14:06:10 +01:00
|
|
|
label = nm_ip_address_get_attribute(s_addr, NM_IP_ADDRESS_ATTRIBUTE_LABEL);
|
2014-09-16 16:38:04 -04:00
|
|
|
if (label)
|
|
|
|
|
g_strlcpy(address.label, g_variant_get_string(label, NULL), sizeof(address.label));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-07-07 23:34:41 +02:00
|
|
|
_add_address(self, NULL, &address);
|
2013-06-29 13:33:36 +02:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-07-12 11:33:52 +02:00
|
|
|
/* Routes */
|
2013-07-31 23:07:32 +02:00
|
|
|
for (i = 0; i < nroutes; i++) {
|
2014-10-19 17:30:10 -04:00
|
|
|
NMIPRoute * s_route = nm_setting_ip_config_get_route(setting, i);
|
2013-07-31 23:07:32 +02:00
|
|
|
NMPlatformIP4Route route;
|
2020-07-03 15:25:51 +02:00
|
|
|
gint64 m;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-08-23 14:43:15 +02:00
|
|
|
if (nm_ip_route_get_family(s_route) != AF_INET) {
|
|
|
|
|
nm_assert_not_reached();
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-07-31 23:07:32 +02:00
|
|
|
memset(&route, 0, sizeof(route));
|
2014-09-16 16:42:46 -04:00
|
|
|
nm_ip_route_get_dest_binary(s_route, &route.network);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2014-09-16 16:42:46 -04:00
|
|
|
route.plen = nm_ip_route_get_prefix(s_route);
|
2016-04-06 14:19:05 +02:00
|
|
|
nm_assert(route.plen <= 32);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2014-09-16 16:42:46 -04:00
|
|
|
nm_ip_route_get_next_hop_binary(s_route, &route.gateway);
|
2020-07-03 15:25:51 +02:00
|
|
|
m = nm_ip_route_get_metric(s_route);
|
|
|
|
|
if (m < 0)
|
all: rework configuring route table support by adding "route-table" setting
We added "ipv4.route-table-sync" and "ipv6.route-table-sync" to not change
behavior for users that configured policy routing outside of NetworkManager,
for example, via a dispatcher script. Users had to explicitly opt-in
for NetworkManager to fully manage all routing tables.
These settings were awkward. Replace them with new settings "ipv4.route-table"
and "ipv6.route-table". Note that this commit breaks API/ABI on the unstable
development branch by removing recently added API.
As before, a connection will have no route-table set by default. This
has the meaning that policy-routing is not enabled and only the main table
will be fully synced. Once the user sets a table, we recognize that and
NetworkManager manages all routing tables.
The new route-table setting has other important uses: analog to
"ipv4.route-metric", it is the default that applies to all routes.
Currently it only works for static routes, not DHCP, SLAAC,
default-route, etc. That will be implemented later.
For static routes, each route still can explicitly set a table, and
overwrite the per-connection setting in "ipv4.route-table" and
"ipv6.route-table".
2017-09-28 08:40:41 +02:00
|
|
|
route.metric = route_metric;
|
2014-11-04 15:48:48 -05:00
|
|
|
else
|
2020-07-03 15:25:51 +02:00
|
|
|
route.metric = m;
|
2016-04-11 13:09:52 +02:00
|
|
|
route.rt_source = NM_IP_CONFIG_SOURCE_USER;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-07-19 11:30:13 +02:00
|
|
|
route.network = nm_utils_ip4_address_clear_host_address(route.network, route.plen);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-07-22 10:33:16 +02:00
|
|
|
nm_utils_ip_route_attribute_to_platform(AF_INET,
|
|
|
|
|
s_route,
|
|
|
|
|
NM_PLATFORM_IP_ROUTE_CAST(&route),
|
|
|
|
|
route_table);
|
2017-09-05 10:36:50 +02:00
|
|
|
_add_route(self, NULL, &route, NULL);
|
2013-07-31 23:07:32 +02:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-07-12 11:33:52 +02:00
|
|
|
/* DNS */
|
2014-10-19 17:30:10 -04:00
|
|
|
if (nm_setting_ip_config_get_ignore_auto_dns(setting)) {
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_reset_nameservers(self);
|
|
|
|
|
nm_ip4_config_reset_domains(self);
|
|
|
|
|
nm_ip4_config_reset_searches(self);
|
2013-07-03 10:26:19 +02:00
|
|
|
}
|
2014-06-24 12:46:03 -04:00
|
|
|
for (i = 0; i < nnameservers; i++) {
|
|
|
|
|
guint32 ip;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2014-10-19 17:30:10 -04:00
|
|
|
if (inet_pton(AF_INET, nm_setting_ip_config_get_dns(setting, i), &ip) == 1)
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_add_nameserver(self, ip);
|
2014-06-24 12:46:03 -04:00
|
|
|
}
|
2013-07-12 11:33:52 +02:00
|
|
|
for (i = 0; i < nsearches; i++)
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_add_search(self, nm_setting_ip_config_get_dns_search(setting, i));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2015-03-26 09:23:12 +01:00
|
|
|
i = 0;
|
|
|
|
|
while ((i = nm_setting_ip_config_next_valid_dns_option(setting, i)) >= 0) {
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_add_dns_option(self, nm_setting_ip_config_get_dns_option(setting, i));
|
2015-03-26 09:23:12 +01:00
|
|
|
i++;
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2016-04-23 15:57:14 +02:00
|
|
|
priority = nm_setting_ip_config_get_dns_priority(setting);
|
|
|
|
|
if (priority)
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_set_dns_priority(self, priority);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
core: implement setting MDNS setting for systemd
The connection.mdns setting is a per-connection setting,
so one might expect that one activated device can only have
one MDNS setting at a time.
However, with certain VPN plugins (those that don't have their
own IP interface, like libreswan), the VPN configuration is merged
into the configuration of the device. So, in this case, there
might be multiple settings for one device that must be merged.
We already have a mechanism for that. It's NMIP4Config. Let NMIP4Config
track this piece of information. Although, stricitly speaking this
is not tied to IPv4, the alternative would be to introduce a new
object to track such data, which would be a tremendous effort
and more complicated then this.
Luckily, NMDnsManager and NMDnsPlugin are already equipped to
handle multiple NMIPConfig instances per device (IPv4 vs. IPv6,
and Device vs. VPN).
Also make "connection.mdns" configurable via global defaults in
NetworkManager.conf.
2017-12-20 14:49:32 +01:00
|
|
|
nm_ip4_config_mdns_set(self, mdns);
|
2018-08-31 15:14:39 +02:00
|
|
|
nm_ip4_config_llmnr_set(self, llmnr);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-09-29 12:06:11 +02:00
|
|
|
nm_ip4_config_set_never_default(self, nm_setting_ip_config_get_never_default(setting));
|
|
|
|
|
|
2017-07-10 14:03:44 +02:00
|
|
|
g_object_thaw_notify(G_OBJECT(self));
|
2008-09-05 02:55:40 +00:00
|
|
|
}
|
2005-04-15 15:43:42 +00:00
|
|
|
|
2014-05-19 10:24:15 -04:00
|
|
|
NMSetting *
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_create_setting(const NMIP4Config *self)
|
2013-07-25 23:36:36 +02:00
|
|
|
{
|
2017-10-04 15:21:21 +02:00
|
|
|
const NMIP4ConfigPrivate * priv;
|
2014-10-19 17:30:10 -04:00
|
|
|
NMSettingIPConfig * s_ip4;
|
2017-07-07 23:34:41 +02:00
|
|
|
guint nnameservers, nsearches, noptions;
|
2013-07-25 23:36:36 +02:00
|
|
|
const char * method = NULL;
|
|
|
|
|
int i;
|
2017-06-12 18:40:14 +02:00
|
|
|
NMDedupMultiIter ipconf_iter;
|
2017-07-07 23:34:41 +02:00
|
|
|
const NMPlatformIP4Address *address;
|
2017-06-12 18:40:14 +02:00
|
|
|
const NMPlatformIP4Route * route;
|
2018-11-26 16:49:51 +01:00
|
|
|
char sbuf[NM_UTILS_INET_ADDRSTRLEN];
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2014-10-19 17:30:10 -04:00
|
|
|
s_ip4 = NM_SETTING_IP_CONFIG(nm_setting_ip4_config_new());
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-07-10 14:03:44 +02:00
|
|
|
if (!self) {
|
2014-05-19 10:24:15 -04:00
|
|
|
g_object_set(s_ip4,
|
2014-10-19 17:30:10 -04:00
|
|
|
NM_SETTING_IP_CONFIG_METHOD,
|
|
|
|
|
NM_SETTING_IP4_CONFIG_METHOD_DISABLED,
|
2014-05-19 10:24:15 -04:00
|
|
|
NULL);
|
|
|
|
|
return NM_SETTING(s_ip4);
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-10-04 15:21:21 +02:00
|
|
|
priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-07-10 14:03:44 +02:00
|
|
|
nnameservers = nm_ip4_config_get_num_nameservers(self);
|
|
|
|
|
nsearches = nm_ip4_config_get_num_searches(self);
|
|
|
|
|
noptions = nm_ip4_config_get_num_dns_options(self);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-07-25 23:36:36 +02:00
|
|
|
/* Addresses */
|
2017-07-07 23:34:41 +02:00
|
|
|
nm_ip_config_iter_ip4_address_for_each (&ipconf_iter, self, &address) {
|
2014-09-16 16:42:46 -04:00
|
|
|
NMIPAddress *s_addr;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-07-04 20:40:18 +02:00
|
|
|
/* Detect dynamic address */
|
|
|
|
|
if (address->lifetime != NM_PLATFORM_LIFETIME_PERMANENT) {
|
|
|
|
|
method = NM_SETTING_IP4_CONFIG_METHOD_AUTO;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-07-25 23:36:36 +02:00
|
|
|
/* Static address found. */
|
|
|
|
|
if (!method)
|
|
|
|
|
method = NM_SETTING_IP4_CONFIG_METHOD_MANUAL;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2014-10-20 21:30:56 -04:00
|
|
|
s_addr = nm_ip_address_new_binary(AF_INET, &address->address, address->plen, NULL);
|
2014-09-16 16:38:04 -04:00
|
|
|
if (*address->label)
|
2017-12-11 14:06:10 +01:00
|
|
|
nm_ip_address_set_attribute(s_addr,
|
|
|
|
|
NM_IP_ADDRESS_ATTRIBUTE_LABEL,
|
|
|
|
|
g_variant_new_string(address->label));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2014-10-19 17:30:10 -04:00
|
|
|
nm_setting_ip_config_add_address(s_ip4, s_addr);
|
2014-09-16 16:42:46 -04:00
|
|
|
nm_ip_address_unref(s_addr);
|
2013-07-25 23:36:36 +02:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2014-10-20 21:30:56 -04:00
|
|
|
/* Gateway */
|
2014-11-07 16:34:13 +01:00
|
|
|
if (priv->best_default_route && nm_setting_ip_config_get_num_addresses(s_ip4) > 0) {
|
2014-10-20 21:30:56 -04:00
|
|
|
g_object_set(
|
|
|
|
|
s_ip4,
|
2017-10-04 15:21:21 +02:00
|
|
|
NM_SETTING_IP_CONFIG_GATEWAY,
|
2020-01-09 11:29:27 +01:00
|
|
|
_nm_utils_inet4_ntop(NMP_OBJECT_CAST_IP4_ROUTE(priv->best_default_route)->gateway,
|
|
|
|
|
sbuf),
|
2014-10-20 21:30:56 -04:00
|
|
|
NULL);
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2014-05-19 10:24:15 -04:00
|
|
|
/* Use 'disabled' if the method wasn't previously set */
|
|
|
|
|
if (!method)
|
2013-07-25 23:36:36 +02:00
|
|
|
method = NM_SETTING_IP4_CONFIG_METHOD_DISABLED;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2015-06-04 15:57:42 +02:00
|
|
|
g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, method, NULL);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-07-25 23:36:36 +02:00
|
|
|
/* Routes */
|
2017-07-07 23:34:41 +02:00
|
|
|
nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, self, &route) {
|
2014-09-16 16:42:46 -04:00
|
|
|
NMIPRoute *s_route;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-08-31 13:39:04 +02:00
|
|
|
if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT(route))
|
2013-07-25 23:36:36 +02:00
|
|
|
continue;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2014-05-08 14:56:59 -04:00
|
|
|
/* Ignore routes provided by external sources */
|
2016-05-16 09:36:09 +02:00
|
|
|
if (route->rt_source
|
|
|
|
|
!= nmp_utils_ip_config_source_round_trip_rtprot(NM_IP_CONFIG_SOURCE_USER))
|
2014-05-08 14:56:59 -04:00
|
|
|
continue;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2014-09-16 16:42:46 -04:00
|
|
|
s_route = nm_ip_route_new_binary(AF_INET,
|
2020-07-03 15:25:51 +02:00
|
|
|
&route->network,
|
|
|
|
|
route->plen,
|
|
|
|
|
&route->gateway,
|
|
|
|
|
route->metric,
|
2014-09-16 16:42:46 -04:00
|
|
|
NULL);
|
2014-10-19 17:30:10 -04:00
|
|
|
nm_setting_ip_config_add_route(s_ip4, s_route);
|
2014-09-16 16:42:46 -04:00
|
|
|
nm_ip_route_unref(s_route);
|
2013-07-25 23:36:36 +02:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-07-25 23:36:36 +02:00
|
|
|
/* DNS */
|
|
|
|
|
for (i = 0; i < nnameservers; i++) {
|
2017-07-10 14:03:44 +02:00
|
|
|
guint32 nameserver = nm_ip4_config_get_nameserver(self, i);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-01-09 11:29:27 +01:00
|
|
|
nm_setting_ip_config_add_dns(s_ip4, _nm_utils_inet4_ntop(nameserver, sbuf));
|
2013-07-25 23:36:36 +02:00
|
|
|
}
|
|
|
|
|
for (i = 0; i < nsearches; i++) {
|
2017-07-10 14:03:44 +02:00
|
|
|
const char *search = nm_ip4_config_get_search(self, i);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2014-10-19 17:30:10 -04:00
|
|
|
nm_setting_ip_config_add_dns_search(s_ip4, search);
|
2013-07-25 23:36:36 +02:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2015-03-26 09:23:12 +01:00
|
|
|
for (i = 0; i < noptions; i++) {
|
2017-07-10 14:03:44 +02:00
|
|
|
const char *option = nm_ip4_config_get_dns_option(self, i);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2015-03-26 09:23:12 +01:00
|
|
|
nm_setting_ip_config_add_dns_option(s_ip4, option);
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2016-04-23 15:57:14 +02:00
|
|
|
g_object_set(s_ip4,
|
|
|
|
|
NM_SETTING_IP_CONFIG_DNS_PRIORITY,
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_get_dns_priority(self),
|
2016-04-23 15:57:14 +02:00
|
|
|
NULL);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2014-05-19 10:24:15 -04:00
|
|
|
return NM_SETTING(s_ip4);
|
2013-07-25 23:36:36 +02:00
|
|
|
}
|
|
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2013-07-03 10:26:19 +02:00
|
|
|
|
2013-08-01 10:34:46 -05:00
|
|
|
void
|
2017-10-04 15:21:21 +02:00
|
|
|
nm_ip4_config_merge(NMIP4Config * dst,
|
|
|
|
|
const NMIP4Config * src,
|
|
|
|
|
NMIPConfigMergeFlags merge_flags,
|
|
|
|
|
guint32 default_route_metric_penalty)
|
2013-08-01 10:34:46 -05:00
|
|
|
{
|
2016-05-11 18:50:10 +02:00
|
|
|
NMIP4ConfigPrivate * dst_priv;
|
|
|
|
|
const NMIP4ConfigPrivate * src_priv;
|
2013-08-01 10:34:46 -05:00
|
|
|
guint32 i;
|
2017-06-12 18:40:14 +02:00
|
|
|
NMDedupMultiIter ipconf_iter;
|
2017-07-07 23:34:41 +02:00
|
|
|
const NMPlatformIP4Address *address = NULL;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-08-01 10:34:46 -05:00
|
|
|
g_return_if_fail(src != NULL);
|
|
|
|
|
g_return_if_fail(dst != NULL);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2015-06-04 15:57:42 +02:00
|
|
|
dst_priv = NM_IP4_CONFIG_GET_PRIVATE(dst);
|
|
|
|
|
src_priv = NM_IP4_CONFIG_GET_PRIVATE(src);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-09-06 11:56:41 +02:00
|
|
|
g_object_freeze_notify(G_OBJECT(dst));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-08-01 10:34:46 -05:00
|
|
|
/* addresses */
|
2019-10-17 10:03:55 +02:00
|
|
|
nm_ip_config_iter_ip4_address_for_each (&ipconf_iter, src, &address) {
|
|
|
|
|
if (NM_FLAGS_HAS(merge_flags, NM_IP_CONFIG_MERGE_EXTERNAL) && !address->external) {
|
|
|
|
|
NMPlatformIP4Address a;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2019-10-17 10:03:55 +02:00
|
|
|
a = *address;
|
|
|
|
|
a.external = TRUE;
|
|
|
|
|
_add_address(dst, NULL, &a);
|
|
|
|
|
} else
|
|
|
|
|
_add_address(dst, NMP_OBJECT_UP_CAST(address), NULL);
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-08-01 10:34:46 -05:00
|
|
|
/* nameservers */
|
2015-08-05 10:01:39 +02:00
|
|
|
if (!NM_FLAGS_HAS(merge_flags, NM_IP_CONFIG_MERGE_NO_DNS)) {
|
|
|
|
|
for (i = 0; i < nm_ip4_config_get_num_nameservers(src); i++)
|
|
|
|
|
nm_ip4_config_add_nameserver(dst, nm_ip4_config_get_nameserver(src, i));
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-08-01 10:34:46 -05:00
|
|
|
/* routes */
|
2015-08-05 10:01:39 +02:00
|
|
|
if (!NM_FLAGS_HAS(merge_flags, NM_IP_CONFIG_MERGE_NO_ROUTES)) {
|
2017-10-04 15:21:21 +02:00
|
|
|
const NMPlatformIP4Route *r_src;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-10-04 15:21:21 +02:00
|
|
|
nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, src, &r_src) {
|
|
|
|
|
if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT(r_src)) {
|
wireguard: don't let explicit gateway override WireGuard's peer route
The profile's "ipv4.gateway" and "ipv6.gateway" has only one real
purpose: to define the next hop of a static default route.
Usually, when specifying a gateway in this way, the default route from
other addressing methods (like DHCPv4 or IPv6 autoconf) gets ignored.
If you have a WireGuard peer with "AllowedIPs=0.0.0.0/0" and
"wireguard.peer-routes" enabled, NetworkManager would automatically add
a route to the peer. Previously, if the user also set a gateway, that
route was suppressed.
That doesn't feel right. Note that configuring a gateway on a WireGuard
profile is likely to be wrong to begin with. At least, unless you take
otherwise care to avoid routing loops. If you take care, setting a
gateway may work, but it would feel clearer to instead just add an
explicit /0 manual route instead.
Also, note that usually you don't need a gateway anyway. WireGuard is a
Layer 3 (IP) tunnel, where the next hop is alway just the other side of
the tunnel. The next hop has little effect on the routes that you
configure on a WireGuard interface. What however matters is whether a
default route is present or not.
Also, an explicit gateway probably works badly with "ipv[46].ip4-auto-default-route",
because in that case the automatism should add a /0 peer-route route in a
separate routing table. The explicit gateway interferes with that too.
Nonetheless, without this patch it's not obvious why the /0 peer
route gets suppressed when a gateway is set. Don't allow for that, and
always add the peer-route.
Probably the profile's gateway setting is still wrong and causes the
profile not to work. But at least, you see all routes configured, and
it's clearer where the (wrong) default route to the gateway comes from.
(cherry picked from commit 115291a46f52ee4adfe85264b9566d216bcb25e8)
2020-04-22 10:46:17 +02:00
|
|
|
if (NM_FLAGS_HAS(merge_flags, NM_IP_CONFIG_MERGE_NO_DEFAULT_ROUTES)
|
|
|
|
|
&& !NM_FLAGS_HAS(src_priv->config_flags,
|
|
|
|
|
NM_IP_CONFIG_FLAGS_IGNORE_MERGE_NO_DEFAULT_ROUTES))
|
2017-10-04 15:21:21 +02:00
|
|
|
continue;
|
|
|
|
|
if (default_route_metric_penalty) {
|
|
|
|
|
NMPlatformIP4Route r = *r_src;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-07-03 15:25:51 +02:00
|
|
|
r.metric =
|
|
|
|
|
nm_utils_ip_route_metric_penalize(r.metric, default_route_metric_penalty);
|
2017-10-04 15:21:21 +02:00
|
|
|
_add_route(dst, NULL, &r, NULL);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
2017-08-31 13:39:04 +02:00
|
|
|
_add_route(dst, ipconf_iter.current->obj, NULL, NULL);
|
2015-08-05 10:01:39 +02:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
|
|
|
|
|
2013-08-01 10:34:46 -05:00
|
|
|
/* domains */
|
2015-08-05 10:01:39 +02:00
|
|
|
if (!NM_FLAGS_HAS(merge_flags, NM_IP_CONFIG_MERGE_NO_DNS)) {
|
|
|
|
|
for (i = 0; i < nm_ip4_config_get_num_domains(src); i++)
|
|
|
|
|
nm_ip4_config_add_domain(dst, nm_ip4_config_get_domain(src, i));
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-08-01 10:34:46 -05:00
|
|
|
/* dns searches */
|
2015-08-05 10:01:39 +02:00
|
|
|
if (!NM_FLAGS_HAS(merge_flags, NM_IP_CONFIG_MERGE_NO_DNS)) {
|
|
|
|
|
for (i = 0; i < nm_ip4_config_get_num_searches(src); i++)
|
|
|
|
|
nm_ip4_config_add_search(dst, nm_ip4_config_get_search(src, i));
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2015-03-26 09:23:12 +01:00
|
|
|
/* dns options */
|
2015-08-05 10:01:39 +02:00
|
|
|
if (!NM_FLAGS_HAS(merge_flags, NM_IP_CONFIG_MERGE_NO_DNS)) {
|
|
|
|
|
for (i = 0; i < nm_ip4_config_get_num_dns_options(src); i++)
|
|
|
|
|
nm_ip4_config_add_dns_option(dst, nm_ip4_config_get_dns_option(src, i));
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2014-04-17 11:15:36 +02:00
|
|
|
/* MTU */
|
2017-01-15 12:57:50 +01:00
|
|
|
if (src_priv->mtu_source > dst_priv->mtu_source
|
|
|
|
|
|| (src_priv->mtu_source == dst_priv->mtu_source
|
|
|
|
|
&& ((!dst_priv->mtu && src_priv->mtu)
|
|
|
|
|
|| (dst_priv->mtu && src_priv->mtu < dst_priv->mtu))))
|
|
|
|
|
nm_ip4_config_set_mtu(dst, src_priv->mtu, src_priv->mtu_source);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-08-01 10:34:46 -05:00
|
|
|
/* NIS */
|
2015-08-05 10:01:39 +02:00
|
|
|
if (!NM_FLAGS_HAS(merge_flags, NM_IP_CONFIG_MERGE_NO_DNS)) {
|
|
|
|
|
for (i = 0; i < nm_ip4_config_get_num_nis_servers(src); i++)
|
|
|
|
|
nm_ip4_config_add_nis_server(dst, nm_ip4_config_get_nis_server(src, i));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2015-08-05 10:01:39 +02:00
|
|
|
if (nm_ip4_config_get_nis_domain(src))
|
|
|
|
|
nm_ip4_config_set_nis_domain(dst, nm_ip4_config_get_nis_domain(src));
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-08-01 10:34:46 -05:00
|
|
|
/* WINS */
|
2015-08-05 10:01:39 +02:00
|
|
|
if (!NM_FLAGS_HAS(merge_flags, NM_IP_CONFIG_MERGE_NO_DNS)) {
|
|
|
|
|
for (i = 0; i < nm_ip4_config_get_num_wins(src); i++)
|
|
|
|
|
nm_ip4_config_add_wins(dst, nm_ip4_config_get_wins(src, i));
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2015-04-30 18:11:16 +02:00
|
|
|
/* metered flag */
|
|
|
|
|
nm_ip4_config_set_metered(dst,
|
|
|
|
|
nm_ip4_config_get_metered(dst) || nm_ip4_config_get_metered(src));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-09-29 12:06:11 +02:00
|
|
|
/* never default */
|
|
|
|
|
nm_ip4_config_set_never_default(dst,
|
|
|
|
|
nm_ip4_config_get_never_default(dst)
|
|
|
|
|
|| nm_ip4_config_get_never_default(src));
|
|
|
|
|
|
2016-04-23 15:57:14 +02:00
|
|
|
/* DNS priority */
|
|
|
|
|
if (nm_ip4_config_get_dns_priority(src))
|
|
|
|
|
nm_ip4_config_set_dns_priority(dst, nm_ip4_config_get_dns_priority(src));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
core: implement setting MDNS setting for systemd
The connection.mdns setting is a per-connection setting,
so one might expect that one activated device can only have
one MDNS setting at a time.
However, with certain VPN plugins (those that don't have their
own IP interface, like libreswan), the VPN configuration is merged
into the configuration of the device. So, in this case, there
might be multiple settings for one device that must be merged.
We already have a mechanism for that. It's NMIP4Config. Let NMIP4Config
track this piece of information. Although, stricitly speaking this
is not tied to IPv4, the alternative would be to introduce a new
object to track such data, which would be a tremendous effort
and more complicated then this.
Luckily, NMDnsManager and NMDnsPlugin are already equipped to
handle multiple NMIPConfig instances per device (IPv4 vs. IPv6,
and Device vs. VPN).
Also make "connection.mdns" configurable via global defaults in
NetworkManager.conf.
2017-12-20 14:49:32 +01:00
|
|
|
/* mdns */
|
|
|
|
|
nm_ip4_config_mdns_set(dst, NM_MAX(nm_ip4_config_mdns_get(src), nm_ip4_config_mdns_get(dst)));
|
2018-08-31 15:14:39 +02:00
|
|
|
/* LLMNR */
|
|
|
|
|
nm_ip4_config_llmnr_set(dst,
|
|
|
|
|
NM_MAX(nm_ip4_config_llmnr_get(src), nm_ip4_config_llmnr_get(dst)));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-09-06 11:56:41 +02:00
|
|
|
g_object_thaw_notify(G_OBJECT(dst));
|
2013-08-01 10:34:46 -05:00
|
|
|
}
|
|
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2014-11-20 23:36:50 +01:00
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
_nameservers_get_index(const NMIP4Config *self, guint32 ns)
|
|
|
|
|
{
|
2016-05-11 18:50:10 +02:00
|
|
|
const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2014-11-20 23:36:50 +01:00
|
|
|
guint i;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < priv->nameservers->len; i++) {
|
|
|
|
|
guint32 n = g_array_index(priv->nameservers, guint32, i);
|
|
|
|
|
|
|
|
|
|
if (ns == n)
|
|
|
|
|
return (int) i;
|
|
|
|
|
}
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
_domains_get_index(const NMIP4Config *self, const char *domain)
|
|
|
|
|
{
|
2016-05-11 18:50:10 +02:00
|
|
|
const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2014-11-20 23:36:50 +01:00
|
|
|
guint i;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < priv->domains->len; i++) {
|
|
|
|
|
const char *d = g_ptr_array_index(priv->domains, i);
|
|
|
|
|
|
|
|
|
|
if (g_strcmp0(domain, d) == 0)
|
|
|
|
|
return (int) i;
|
|
|
|
|
}
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
_searches_get_index(const NMIP4Config *self, const char *search)
|
|
|
|
|
{
|
2016-05-11 18:50:10 +02:00
|
|
|
const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2014-11-20 23:36:50 +01:00
|
|
|
guint i;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < priv->searches->len; i++) {
|
|
|
|
|
const char *s = g_ptr_array_index(priv->searches, i);
|
|
|
|
|
|
|
|
|
|
if (g_strcmp0(search, s) == 0)
|
|
|
|
|
return (int) i;
|
|
|
|
|
}
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-26 09:23:12 +01:00
|
|
|
static int
|
|
|
|
|
_dns_options_get_index(const NMIP4Config *self, const char *option)
|
|
|
|
|
{
|
2016-05-11 18:50:10 +02:00
|
|
|
const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2015-03-26 09:23:12 +01:00
|
|
|
guint i;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < priv->dns_options->len; i++) {
|
|
|
|
|
const char *s = g_ptr_array_index(priv->dns_options, i);
|
|
|
|
|
|
|
|
|
|
if (g_strcmp0(option, s) == 0)
|
|
|
|
|
return (int) i;
|
|
|
|
|
}
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-20 23:36:50 +01:00
|
|
|
static int
|
|
|
|
|
_nis_servers_get_index(const NMIP4Config *self, guint32 nis_server)
|
|
|
|
|
{
|
2016-05-11 18:50:10 +02:00
|
|
|
const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2014-11-20 23:36:50 +01:00
|
|
|
guint i;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < priv->nis->len; i++) {
|
|
|
|
|
guint32 n = g_array_index(priv->nis, guint32, i);
|
|
|
|
|
|
|
|
|
|
if (n == nis_server)
|
|
|
|
|
return (int) i;
|
|
|
|
|
}
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
_wins_get_index(const NMIP4Config *self, guint32 wins_server)
|
|
|
|
|
{
|
2016-05-11 18:50:10 +02:00
|
|
|
const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2014-11-20 23:36:50 +01:00
|
|
|
guint i;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < priv->wins->len; i++) {
|
|
|
|
|
guint32 n = g_array_index(priv->wins, guint32, i);
|
|
|
|
|
|
|
|
|
|
if (n == wins_server)
|
|
|
|
|
return (int) i;
|
|
|
|
|
}
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2014-11-20 23:36:50 +01:00
|
|
|
|
2013-08-01 14:04:35 -05:00
|
|
|
/**
|
2013-09-06 11:02:03 +02:00
|
|
|
* nm_ip4_config_subtract:
|
2013-08-01 14:04:35 -05:00
|
|
|
* @dst: config from which to remove everything in @src
|
|
|
|
|
* @src: config to remove from @dst
|
2017-10-04 15:21:21 +02:00
|
|
|
* @default_route_metric_penalty: pretend that on source we applied
|
|
|
|
|
* a route penalty on the default-route. It means, for default routes
|
|
|
|
|
* we don't remove routes that match exactly, but those with a lower
|
|
|
|
|
* metric (with the penalty removed).
|
2013-08-01 14:04:35 -05:00
|
|
|
*
|
|
|
|
|
* Removes everything in @src from @dst.
|
|
|
|
|
*/
|
|
|
|
|
void
|
2017-10-04 15:21:21 +02:00
|
|
|
nm_ip4_config_subtract(NMIP4Config * dst,
|
|
|
|
|
const NMIP4Config *src,
|
|
|
|
|
guint32 default_route_metric_penalty)
|
2013-08-01 14:04:35 -05:00
|
|
|
{
|
2017-08-30 11:39:07 +02:00
|
|
|
NMIP4ConfigPrivate * dst_priv;
|
2017-06-12 18:40:14 +02:00
|
|
|
guint i;
|
all: don't use gchar/gshort/gint/glong but C types
We commonly don't use the glib typedefs for char/short/int/long,
but their C types directly.
$ git grep '\<g\(char\|short\|int\|long\|float\|double\)\>' | wc -l
587
$ git grep '\<\(char\|short\|int\|long\|float\|double\)\>' | wc -l
21114
One could argue that using the glib typedefs is preferable in
public API (of our glib based libnm library) or where it clearly
is related to glib, like during
g_object_set (obj, PROPERTY, (gint) value, NULL);
However, that argument does not seem strong, because in practice we don't
follow that argument today, and seldomly use the glib typedefs.
Also, the style guide for this would be hard to formalize, because
"using them where clearly related to a glib" is a very loose suggestion.
Also note that glib typedefs will always just be typedefs of the
underlying C types. There is no danger of glib changing the meaning
of these typedefs (because that would be a major API break of glib).
A simple style guide is instead: don't use these typedefs.
No manual actions, I only ran the bash script:
FILES=($(git ls-files '*.[hc]'))
sed -i \
-e 's/\<g\(char\|short\|int\|long\|float\|double\)\>\( [^ ]\)/\1\2/g' \
-e 's/\<g\(char\|short\|int\|long\|float\|double\)\> /\1 /g' \
-e 's/\<g\(char\|short\|int\|long\|float\|double\)\>/\1/g' \
"${FILES[@]}"
2018-07-11 07:40:19 +02:00
|
|
|
int idx;
|
2017-07-07 23:34:41 +02:00
|
|
|
const NMPlatformIP4Address *a;
|
2017-06-12 18:40:14 +02:00
|
|
|
const NMPlatformIP4Route * r;
|
|
|
|
|
NMDedupMultiIter ipconf_iter;
|
2017-07-07 23:34:41 +02:00
|
|
|
gboolean changed;
|
2017-08-31 13:39:04 +02:00
|
|
|
gboolean changed_default_route;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-08-01 14:04:35 -05:00
|
|
|
g_return_if_fail(src != NULL);
|
|
|
|
|
g_return_if_fail(dst != NULL);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-08-30 11:39:07 +02:00
|
|
|
dst_priv = NM_IP4_CONFIG_GET_PRIVATE(dst);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-09-06 11:56:41 +02:00
|
|
|
g_object_freeze_notify(G_OBJECT(dst));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-08-01 14:04:35 -05:00
|
|
|
/* addresses */
|
2017-07-07 23:34:41 +02:00
|
|
|
changed = FALSE;
|
|
|
|
|
nm_ip_config_iter_ip4_address_for_each (&ipconf_iter, src, &a) {
|
2017-08-30 11:39:07 +02:00
|
|
|
if (nm_dedup_multi_index_remove_obj(dst_priv->multi_idx,
|
|
|
|
|
&dst_priv->idx_ip4_addresses,
|
2017-08-23 16:00:11 +02:00
|
|
|
NMP_OBJECT_UP_CAST(a),
|
|
|
|
|
NULL))
|
2017-07-07 23:34:41 +02:00
|
|
|
changed = TRUE;
|
2013-08-01 14:04:35 -05:00
|
|
|
}
|
2017-07-07 23:34:41 +02:00
|
|
|
if (changed)
|
|
|
|
|
_notify_addresses(dst);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-08-01 14:04:35 -05:00
|
|
|
/* nameservers */
|
|
|
|
|
for (i = 0; i < nm_ip4_config_get_num_nameservers(src); i++) {
|
2014-11-20 23:36:50 +01:00
|
|
|
idx = _nameservers_get_index(dst, nm_ip4_config_get_nameserver(src, i));
|
|
|
|
|
if (idx >= 0)
|
|
|
|
|
nm_ip4_config_del_nameserver(dst, idx);
|
2013-08-01 14:04:35 -05:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-08-01 14:04:35 -05:00
|
|
|
/* routes */
|
2017-07-07 23:34:41 +02:00
|
|
|
changed = FALSE;
|
2017-08-31 13:39:04 +02:00
|
|
|
changed_default_route = FALSE;
|
2017-07-07 23:34:41 +02:00
|
|
|
nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, src, &r) {
|
2017-10-04 15:21:21 +02:00
|
|
|
const NMPObject * o_src = NMP_OBJECT_UP_CAST(r);
|
|
|
|
|
NMPObject o_lookup_copy;
|
|
|
|
|
const NMPObject * o_lookup;
|
2017-08-31 13:39:04 +02:00
|
|
|
nm_auto_nmpobj const NMPObject *obj_old = NULL;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-10-04 15:21:21 +02:00
|
|
|
if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT(r) && default_route_metric_penalty) {
|
|
|
|
|
NMPlatformIP4Route *rr;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-10-04 15:21:21 +02:00
|
|
|
/* the default route was penalized when merging it to the combined ip-config.
|
|
|
|
|
* When subtracting the routes, we must re-do that process when comparing
|
|
|
|
|
* the routes. */
|
|
|
|
|
o_lookup = nmp_object_stackinit_obj(&o_lookup_copy, o_src);
|
|
|
|
|
rr = NMP_OBJECT_CAST_IP4_ROUTE(&o_lookup_copy);
|
2020-07-03 15:25:51 +02:00
|
|
|
rr->metric =
|
|
|
|
|
nm_utils_ip_route_metric_penalize(rr->metric, default_route_metric_penalty);
|
2017-10-04 15:21:21 +02:00
|
|
|
} else
|
|
|
|
|
o_lookup = o_src;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-08-30 11:39:07 +02:00
|
|
|
if (nm_dedup_multi_index_remove_obj(dst_priv->multi_idx,
|
|
|
|
|
&dst_priv->idx_ip4_routes,
|
2017-10-04 15:21:21 +02:00
|
|
|
o_lookup,
|
2017-08-31 13:39:04 +02:00
|
|
|
(gconstpointer *) &obj_old)) {
|
|
|
|
|
if (dst_priv->best_default_route == obj_old) {
|
|
|
|
|
nm_clear_nmp_object(&dst_priv->best_default_route);
|
|
|
|
|
changed_default_route = TRUE;
|
|
|
|
|
}
|
2017-07-07 23:34:41 +02:00
|
|
|
changed = TRUE;
|
2017-08-31 13:39:04 +02:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
2017-08-31 13:39:04 +02:00
|
|
|
if (changed_default_route) {
|
2020-07-21 17:49:23 +02:00
|
|
|
nmp_object_ref_set(&dst_priv->best_default_route,
|
|
|
|
|
_nm_ip4_config_best_default_route_find(dst));
|
2017-10-04 15:21:21 +02:00
|
|
|
_notify(dst, PROP_GATEWAY);
|
2013-08-01 14:04:35 -05:00
|
|
|
}
|
2017-07-07 23:34:41 +02:00
|
|
|
if (changed)
|
|
|
|
|
_notify_routes(dst);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-08-01 14:04:35 -05:00
|
|
|
/* domains */
|
|
|
|
|
for (i = 0; i < nm_ip4_config_get_num_domains(src); i++) {
|
2014-11-20 23:36:50 +01:00
|
|
|
idx = _domains_get_index(dst, nm_ip4_config_get_domain(src, i));
|
|
|
|
|
if (idx >= 0)
|
|
|
|
|
nm_ip4_config_del_domain(dst, idx);
|
2013-08-01 14:04:35 -05:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-08-01 14:04:35 -05:00
|
|
|
/* dns searches */
|
|
|
|
|
for (i = 0; i < nm_ip4_config_get_num_searches(src); i++) {
|
2014-11-20 23:36:50 +01:00
|
|
|
idx = _searches_get_index(dst, nm_ip4_config_get_search(src, i));
|
|
|
|
|
if (idx >= 0)
|
|
|
|
|
nm_ip4_config_del_search(dst, idx);
|
2013-08-01 14:04:35 -05:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2015-03-26 09:23:12 +01:00
|
|
|
/* dns options */
|
|
|
|
|
for (i = 0; i < nm_ip4_config_get_num_dns_options(src); i++) {
|
|
|
|
|
idx = _dns_options_get_index(dst, nm_ip4_config_get_dns_option(src, i));
|
|
|
|
|
if (idx >= 0)
|
|
|
|
|
nm_ip4_config_del_dns_option(dst, idx);
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2014-04-17 11:15:36 +02:00
|
|
|
/* MTU */
|
2017-01-15 12:57:50 +01:00
|
|
|
if (nm_ip4_config_get_mtu(src) == nm_ip4_config_get_mtu(dst)
|
|
|
|
|
&& nm_ip4_config_get_mtu_source(src) == nm_ip4_config_get_mtu_source(dst))
|
2014-10-09 18:51:11 +02:00
|
|
|
nm_ip4_config_set_mtu(dst, 0, NM_IP_CONFIG_SOURCE_UNKNOWN);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-08-01 14:04:35 -05:00
|
|
|
/* NIS */
|
|
|
|
|
for (i = 0; i < nm_ip4_config_get_num_nis_servers(src); i++) {
|
2014-11-20 23:36:50 +01:00
|
|
|
idx = _nis_servers_get_index(dst, nm_ip4_config_get_nis_server(src, i));
|
|
|
|
|
if (idx >= 0)
|
|
|
|
|
nm_ip4_config_del_nis_server(dst, idx);
|
2013-08-01 14:04:35 -05:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-08-01 14:04:35 -05:00
|
|
|
if (g_strcmp0(nm_ip4_config_get_nis_domain(src), nm_ip4_config_get_nis_domain(dst)) == 0)
|
|
|
|
|
nm_ip4_config_set_nis_domain(dst, NULL);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-08-01 14:04:35 -05:00
|
|
|
/* WINS */
|
|
|
|
|
for (i = 0; i < nm_ip4_config_get_num_wins(src); i++) {
|
2014-11-20 23:36:50 +01:00
|
|
|
idx = _wins_get_index(dst, nm_ip4_config_get_wins(src, i));
|
|
|
|
|
if (idx >= 0)
|
|
|
|
|
nm_ip4_config_del_wins(dst, idx);
|
2013-08-01 14:04:35 -05:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2016-04-23 15:57:14 +02:00
|
|
|
/* DNS priority */
|
|
|
|
|
if (nm_ip4_config_get_dns_priority(src) == nm_ip4_config_get_dns_priority(dst))
|
|
|
|
|
nm_ip4_config_set_dns_priority(dst, 0);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
core: implement setting MDNS setting for systemd
The connection.mdns setting is a per-connection setting,
so one might expect that one activated device can only have
one MDNS setting at a time.
However, with certain VPN plugins (those that don't have their
own IP interface, like libreswan), the VPN configuration is merged
into the configuration of the device. So, in this case, there
might be multiple settings for one device that must be merged.
We already have a mechanism for that. It's NMIP4Config. Let NMIP4Config
track this piece of information. Although, stricitly speaking this
is not tied to IPv4, the alternative would be to introduce a new
object to track such data, which would be a tremendous effort
and more complicated then this.
Luckily, NMDnsManager and NMDnsPlugin are already equipped to
handle multiple NMIPConfig instances per device (IPv4 vs. IPv6,
and Device vs. VPN).
Also make "connection.mdns" configurable via global defaults in
NetworkManager.conf.
2017-12-20 14:49:32 +01:00
|
|
|
/* mdns */
|
|
|
|
|
if (nm_ip4_config_mdns_get(src) == nm_ip4_config_mdns_get(dst))
|
|
|
|
|
nm_ip4_config_mdns_set(dst, NM_SETTING_CONNECTION_MDNS_DEFAULT);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2018-08-31 15:14:39 +02:00
|
|
|
/* LLMNR */
|
|
|
|
|
if (nm_ip4_config_llmnr_get(src) == nm_ip4_config_llmnr_get(dst))
|
|
|
|
|
nm_ip4_config_llmnr_set(dst, NM_SETTING_CONNECTION_LLMNR_DEFAULT);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-09-06 11:56:41 +02:00
|
|
|
g_object_thaw_notify(G_OBJECT(dst));
|
2013-08-01 14:04:35 -05:00
|
|
|
}
|
|
|
|
|
|
2017-11-20 14:59:32 +01:00
|
|
|
static gboolean
|
|
|
|
|
_nm_ip4_config_intersect_helper(NMIP4Config * dst,
|
|
|
|
|
const NMIP4Config *src,
|
2019-03-08 15:50:39 +01:00
|
|
|
gboolean intersect_addresses,
|
2018-09-21 17:55:46 +02:00
|
|
|
gboolean intersect_routes,
|
2017-11-20 14:59:32 +01:00
|
|
|
guint32 default_route_metric_penalty,
|
|
|
|
|
gboolean update_dst)
|
2014-11-20 23:39:21 +01:00
|
|
|
{
|
2017-08-30 11:39:07 +02:00
|
|
|
NMIP4ConfigPrivate * dst_priv;
|
|
|
|
|
const NMIP4ConfigPrivate * src_priv;
|
2017-06-12 18:40:14 +02:00
|
|
|
NMDedupMultiIter ipconf_iter;
|
2017-07-07 23:34:41 +02:00
|
|
|
const NMPlatformIP4Address *a;
|
2017-06-12 18:40:14 +02:00
|
|
|
const NMPlatformIP4Route * r;
|
2017-08-31 13:39:04 +02:00
|
|
|
const NMPObject * new_best_default_route;
|
2017-11-20 14:59:32 +01:00
|
|
|
gboolean changed, result = FALSE;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-11-20 14:59:32 +01:00
|
|
|
g_return_val_if_fail(src, FALSE);
|
|
|
|
|
g_return_val_if_fail(dst, FALSE);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-08-30 11:39:07 +02:00
|
|
|
dst_priv = NM_IP4_CONFIG_GET_PRIVATE(dst);
|
|
|
|
|
src_priv = NM_IP4_CONFIG_GET_PRIVATE(src);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-11-20 14:59:32 +01:00
|
|
|
if (update_dst)
|
|
|
|
|
g_object_freeze_notify(G_OBJECT(dst));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2014-11-20 23:39:21 +01:00
|
|
|
/* addresses */
|
2019-03-08 15:50:39 +01:00
|
|
|
if (intersect_addresses) {
|
|
|
|
|
changed = FALSE;
|
|
|
|
|
nm_ip_config_iter_ip4_address_for_each (&ipconf_iter, dst, &a) {
|
|
|
|
|
if (nm_dedup_multi_index_lookup_obj(src_priv->multi_idx,
|
|
|
|
|
&src_priv->idx_ip4_addresses,
|
|
|
|
|
NMP_OBJECT_UP_CAST(a)))
|
|
|
|
|
continue;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2019-03-08 15:50:39 +01:00
|
|
|
if (!update_dst)
|
|
|
|
|
return TRUE;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2019-03-08 15:50:39 +01:00
|
|
|
if (nm_dedup_multi_index_remove_entry(dst_priv->multi_idx, ipconf_iter.current) != 1)
|
|
|
|
|
nm_assert_not_reached();
|
|
|
|
|
changed = TRUE;
|
|
|
|
|
}
|
|
|
|
|
if (changed) {
|
|
|
|
|
_notify_addresses(dst);
|
|
|
|
|
result = TRUE;
|
|
|
|
|
}
|
2017-11-20 14:59:32 +01:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2015-01-26 17:29:25 +01:00
|
|
|
/* ignore nameservers */
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2014-11-20 23:39:21 +01:00
|
|
|
/* routes */
|
2018-09-21 17:55:46 +02:00
|
|
|
if (!intersect_routes)
|
|
|
|
|
goto skip_routes;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-08-30 11:42:43 +02:00
|
|
|
changed = FALSE;
|
2017-08-31 13:39:04 +02:00
|
|
|
new_best_default_route = NULL;
|
2017-07-07 23:34:41 +02:00
|
|
|
nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, dst, &r) {
|
2017-10-04 15:21:21 +02:00
|
|
|
const NMPObject *o_dst = NMP_OBJECT_UP_CAST(r);
|
|
|
|
|
const NMPObject *o_lookup;
|
|
|
|
|
NMPObject o_lookup_copy;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-10-04 15:21:21 +02:00
|
|
|
if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT(r) && default_route_metric_penalty) {
|
|
|
|
|
NMPlatformIP4Route *rr;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-10-04 15:21:21 +02:00
|
|
|
/* the default route was penalized when merging it to the combined ip-config.
|
|
|
|
|
* When intersecting the routes, we must re-do that process when comparing
|
|
|
|
|
* the routes. */
|
|
|
|
|
o_lookup = nmp_object_stackinit_obj(&o_lookup_copy, o_dst);
|
|
|
|
|
rr = NMP_OBJECT_CAST_IP4_ROUTE(&o_lookup_copy);
|
2020-07-03 15:25:51 +02:00
|
|
|
rr->metric =
|
|
|
|
|
nm_utils_ip_route_metric_penalize(rr->metric, default_route_metric_penalty);
|
2017-10-04 15:21:21 +02:00
|
|
|
} else
|
|
|
|
|
o_lookup = o_dst;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-08-30 11:39:07 +02:00
|
|
|
if (nm_dedup_multi_index_lookup_obj(src_priv->multi_idx,
|
|
|
|
|
&src_priv->idx_ip4_routes,
|
2017-10-04 15:21:21 +02:00
|
|
|
o_lookup)) {
|
|
|
|
|
new_best_default_route =
|
|
|
|
|
_nm_ip_config_best_default_route_find_better(new_best_default_route, o_dst);
|
2017-06-12 18:40:14 +02:00
|
|
|
continue;
|
2017-08-31 13:39:04 +02:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-11-20 14:59:32 +01:00
|
|
|
if (!update_dst)
|
|
|
|
|
return TRUE;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-08-30 11:39:07 +02:00
|
|
|
if (nm_dedup_multi_index_remove_entry(dst_priv->multi_idx, ipconf_iter.current) != 1)
|
2017-06-12 18:40:14 +02:00
|
|
|
nm_assert_not_reached();
|
2017-08-30 11:42:43 +02:00
|
|
|
changed = TRUE;
|
2014-11-20 23:39:21 +01:00
|
|
|
}
|
2020-07-21 17:49:23 +02:00
|
|
|
if (nmp_object_ref_set(&dst_priv->best_default_route, new_best_default_route)) {
|
2017-08-31 13:39:04 +02:00
|
|
|
nm_assert(changed);
|
2017-10-04 15:21:21 +02:00
|
|
|
_notify(dst, PROP_GATEWAY);
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-11-20 14:59:32 +01:00
|
|
|
if (changed) {
|
2017-08-30 11:42:43 +02:00
|
|
|
_notify_routes(dst);
|
2017-11-20 14:59:32 +01:00
|
|
|
result = TRUE;
|
|
|
|
|
}
|
2014-11-20 23:39:21 +01:00
|
|
|
|
2019-03-08 18:19:00 +01:00
|
|
|
skip_routes:
|
2015-01-26 17:29:25 +01:00
|
|
|
/* ignore domains */
|
|
|
|
|
/* ignore dns searches */
|
2015-03-26 09:23:12 +01:00
|
|
|
/* ignore dns options */
|
2015-01-26 17:29:25 +01:00
|
|
|
/* ignore NIS */
|
|
|
|
|
/* ignore WINS */
|
core: implement setting MDNS setting for systemd
The connection.mdns setting is a per-connection setting,
so one might expect that one activated device can only have
one MDNS setting at a time.
However, with certain VPN plugins (those that don't have their
own IP interface, like libreswan), the VPN configuration is merged
into the configuration of the device. So, in this case, there
might be multiple settings for one device that must be merged.
We already have a mechanism for that. It's NMIP4Config. Let NMIP4Config
track this piece of information. Although, stricitly speaking this
is not tied to IPv4, the alternative would be to introduce a new
object to track such data, which would be a tremendous effort
and more complicated then this.
Luckily, NMDnsManager and NMDnsPlugin are already equipped to
handle multiple NMIPConfig instances per device (IPv4 vs. IPv6,
and Device vs. VPN).
Also make "connection.mdns" configurable via global defaults in
NetworkManager.conf.
2017-12-20 14:49:32 +01:00
|
|
|
/* ignore mdns */
|
2018-08-31 15:14:39 +02:00
|
|
|
/* ignore LLMNR */
|
2014-11-20 23:39:21 +01:00
|
|
|
|
2017-11-20 14:59:32 +01:00
|
|
|
if (update_dst)
|
|
|
|
|
g_object_thaw_notify(G_OBJECT(dst));
|
|
|
|
|
return result;
|
2014-11-20 23:39:21 +01:00
|
|
|
}
|
|
|
|
|
|
2017-11-20 14:59:32 +01:00
|
|
|
/**
|
|
|
|
|
* nm_ip4_config_intersect:
|
|
|
|
|
* @dst: a configuration to be updated
|
|
|
|
|
* @src: another configuration
|
2019-03-08 15:50:39 +01:00
|
|
|
* @intersect_addresses: whether addresses should be intersected
|
|
|
|
|
* @intersect_routes: whether routes should be intersected
|
2017-11-20 14:59:32 +01:00
|
|
|
* @default_route_metric_penalty: the default route metric penalty
|
|
|
|
|
*
|
|
|
|
|
* Computes the intersection between @src and @dst and updates @dst in place
|
|
|
|
|
* with the result.
|
|
|
|
|
*/
|
|
|
|
|
void
|
|
|
|
|
nm_ip4_config_intersect(NMIP4Config * dst,
|
|
|
|
|
const NMIP4Config *src,
|
2019-03-08 15:50:39 +01:00
|
|
|
gboolean intersect_addresses,
|
2018-09-21 17:55:46 +02:00
|
|
|
gboolean intersect_routes,
|
2017-11-20 14:59:32 +01:00
|
|
|
guint32 default_route_metric_penalty)
|
|
|
|
|
{
|
2019-03-08 15:50:39 +01:00
|
|
|
_nm_ip4_config_intersect_helper(dst,
|
|
|
|
|
src,
|
|
|
|
|
intersect_addresses,
|
|
|
|
|
intersect_routes,
|
|
|
|
|
default_route_metric_penalty,
|
|
|
|
|
TRUE);
|
2017-11-20 14:59:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* nm_ip4_config_intersect_alloc:
|
|
|
|
|
* @a: a configuration
|
|
|
|
|
* @b: another configuration
|
2019-03-08 15:50:39 +01:00
|
|
|
* @intersect_addresses: whether addresses should be intersected
|
|
|
|
|
* @intersect_routes: whether routes should be intersected
|
2017-11-20 14:59:32 +01:00
|
|
|
* @default_route_metric_penalty: the default route metric penalty
|
|
|
|
|
*
|
|
|
|
|
* Computes the intersection between @a and @b and returns the result in a newly
|
|
|
|
|
* allocated configuration. As a special case, if @a and @b are identical (with
|
|
|
|
|
* respect to the only properties considered - addresses and routes) the
|
|
|
|
|
* functions returns NULL so that one of existing configuration can be reused
|
|
|
|
|
* without allocation.
|
|
|
|
|
*
|
|
|
|
|
* Returns: the intersection between @a and @b, or %NULL if the result is equal
|
|
|
|
|
* to @a and @b.
|
|
|
|
|
*/
|
|
|
|
|
NMIP4Config *
|
|
|
|
|
nm_ip4_config_intersect_alloc(const NMIP4Config *a,
|
|
|
|
|
const NMIP4Config *b,
|
2019-03-08 15:50:39 +01:00
|
|
|
gboolean intersect_addresses,
|
2018-09-21 17:55:46 +02:00
|
|
|
gboolean intersect_routes,
|
2017-11-20 14:59:32 +01:00
|
|
|
guint32 default_route_metric_penalty)
|
|
|
|
|
{
|
|
|
|
|
NMIP4Config *a_copy;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-11-20 14:59:32 +01:00
|
|
|
if (_nm_ip4_config_intersect_helper((NMIP4Config *) a,
|
|
|
|
|
b,
|
2019-03-08 15:50:39 +01:00
|
|
|
intersect_addresses,
|
2018-09-21 17:55:46 +02:00
|
|
|
intersect_routes,
|
2019-03-08 15:50:39 +01:00
|
|
|
default_route_metric_penalty,
|
|
|
|
|
FALSE)) {
|
2017-11-20 14:59:32 +01:00
|
|
|
a_copy = nm_ip4_config_clone(a);
|
2019-03-08 15:50:39 +01:00
|
|
|
_nm_ip4_config_intersect_helper(a_copy,
|
|
|
|
|
b,
|
|
|
|
|
intersect_addresses,
|
|
|
|
|
intersect_routes,
|
|
|
|
|
default_route_metric_penalty,
|
|
|
|
|
TRUE);
|
2017-11-20 14:59:32 +01:00
|
|
|
return a_copy;
|
|
|
|
|
} else
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
2013-09-06 11:02:03 +02:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* nm_ip4_config_replace:
|
2015-11-26 09:08:46 +01:00
|
|
|
* @dst: config to replace with @src content
|
|
|
|
|
* @src: source config to copy
|
2013-09-06 11:02:03 +02:00
|
|
|
* @relevant_changes: return whether there are changes to the
|
|
|
|
|
* destination object that are relevant. This is equal to
|
|
|
|
|
* nm_ip4_config_equal() showing any difference.
|
|
|
|
|
*
|
|
|
|
|
* Replaces everything in @dst with @src so that the two configurations
|
|
|
|
|
* contain the same content -- with the exception of the dbus path.
|
|
|
|
|
*
|
|
|
|
|
* Returns: whether the @dst instance changed in any way (including minor changes,
|
|
|
|
|
* that are not signaled by the output parameter @relevant_changes).
|
|
|
|
|
*/
|
|
|
|
|
gboolean
|
2013-09-25 13:08:53 +02:00
|
|
|
nm_ip4_config_replace(NMIP4Config *dst, const NMIP4Config *src, gboolean *relevant_changes)
|
2013-09-06 11:02:03 +02:00
|
|
|
{
|
2015-10-10 20:51:17 +02:00
|
|
|
#if NM_MORE_ASSERTS
|
2013-09-06 11:02:03 +02:00
|
|
|
gboolean config_equal;
|
|
|
|
|
#endif
|
|
|
|
|
gboolean has_minor_changes = FALSE, has_relevant_changes = FALSE, are_equal;
|
|
|
|
|
guint i, num;
|
2016-05-11 18:50:10 +02:00
|
|
|
NMIP4ConfigPrivate * dst_priv;
|
|
|
|
|
const NMIP4ConfigPrivate * src_priv;
|
2017-06-12 18:40:14 +02:00
|
|
|
NMDedupMultiIter ipconf_iter_src, ipconf_iter_dst;
|
2017-07-16 19:18:51 +02:00
|
|
|
const NMDedupMultiHeadEntry *head_entry_src;
|
2017-08-31 13:39:04 +02:00
|
|
|
const NMPObject * new_best_default_route;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-09-06 11:02:03 +02:00
|
|
|
g_return_val_if_fail(src != NULL, FALSE);
|
|
|
|
|
g_return_val_if_fail(dst != NULL, FALSE);
|
|
|
|
|
g_return_val_if_fail(src != dst, FALSE);
|
|
|
|
|
|
2015-10-10 20:51:17 +02:00
|
|
|
#if NM_MORE_ASSERTS
|
2013-09-06 11:02:03 +02:00
|
|
|
config_equal = nm_ip4_config_equal(dst, src);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
dst_priv = NM_IP4_CONFIG_GET_PRIVATE(dst);
|
|
|
|
|
src_priv = NM_IP4_CONFIG_GET_PRIVATE(src);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-09-06 11:56:41 +02:00
|
|
|
g_object_freeze_notify(G_OBJECT(dst));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2015-01-19 18:33:10 +01:00
|
|
|
/* ifindex */
|
|
|
|
|
if (src_priv->ifindex != dst_priv->ifindex) {
|
2015-02-20 16:31:10 -06:00
|
|
|
dst_priv->ifindex = src_priv->ifindex;
|
2015-01-19 18:33:10 +01:00
|
|
|
has_minor_changes = TRUE;
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-09-06 11:02:03 +02:00
|
|
|
/* addresses */
|
2017-07-16 19:18:51 +02:00
|
|
|
head_entry_src = nm_ip4_config_lookup_addresses(src);
|
|
|
|
|
nm_dedup_multi_iter_init(&ipconf_iter_src, head_entry_src);
|
2017-07-07 23:34:41 +02:00
|
|
|
nm_ip_config_iter_ip4_address_init(&ipconf_iter_dst, dst);
|
|
|
|
|
are_equal = TRUE;
|
|
|
|
|
while (TRUE) {
|
|
|
|
|
gboolean has;
|
|
|
|
|
const NMPlatformIP4Address *r_src = NULL;
|
|
|
|
|
const NMPlatformIP4Address *r_dst = NULL;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-07-23 12:19:15 +02:00
|
|
|
has = nm_platform_dedup_multi_iter_next_ip4_address(&ipconf_iter_src, &r_src);
|
|
|
|
|
if (has != nm_platform_dedup_multi_iter_next_ip4_address(&ipconf_iter_dst, &r_dst)) {
|
2017-07-07 23:34:41 +02:00
|
|
|
are_equal = FALSE;
|
|
|
|
|
has_relevant_changes = TRUE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (!has)
|
|
|
|
|
break;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-07-07 23:34:41 +02:00
|
|
|
if (nm_platform_ip4_address_cmp(r_src, r_dst) != 0) {
|
|
|
|
|
are_equal = FALSE;
|
2017-09-11 21:41:57 +02:00
|
|
|
if (r_src->address != r_dst->address || r_src->plen != r_dst->plen
|
2017-07-07 23:34:41 +02:00
|
|
|
|| r_src->peer_address != r_dst->peer_address) {
|
|
|
|
|
has_relevant_changes = TRUE;
|
|
|
|
|
break;
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
2013-09-06 11:02:03 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!are_equal) {
|
|
|
|
|
has_minor_changes = TRUE;
|
2017-07-07 23:34:41 +02:00
|
|
|
nm_dedup_multi_index_dirty_set_idx(dst_priv->multi_idx, &dst_priv->idx_ip4_addresses);
|
2017-07-16 19:18:51 +02:00
|
|
|
nm_dedup_multi_iter_for_each (&ipconf_iter_src, head_entry_src) {
|
2017-08-30 14:05:16 +02:00
|
|
|
_nm_ip_config_add_obj(dst_priv->multi_idx,
|
|
|
|
|
&dst_priv->idx_ip4_addresses_,
|
|
|
|
|
dst_priv->ifindex,
|
|
|
|
|
ipconf_iter_src.current->obj,
|
|
|
|
|
NULL,
|
|
|
|
|
FALSE,
|
2017-08-30 19:05:38 +02:00
|
|
|
TRUE,
|
2017-09-05 10:36:50 +02:00
|
|
|
NULL,
|
2017-08-30 19:05:38 +02:00
|
|
|
NULL);
|
2017-07-07 23:34:41 +02:00
|
|
|
}
|
|
|
|
|
nm_dedup_multi_index_dirty_remove_idx(dst_priv->multi_idx,
|
|
|
|
|
&dst_priv->idx_ip4_addresses,
|
|
|
|
|
FALSE);
|
2017-07-25 14:23:10 +02:00
|
|
|
_notify_addresses(dst);
|
2013-09-06 11:02:03 +02:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-09-06 11:02:03 +02:00
|
|
|
/* routes */
|
2017-07-16 19:18:51 +02:00
|
|
|
head_entry_src = nm_ip4_config_lookup_routes(src);
|
|
|
|
|
nm_dedup_multi_iter_init(&ipconf_iter_src, head_entry_src);
|
2017-07-07 23:34:41 +02:00
|
|
|
nm_ip_config_iter_ip4_route_init(&ipconf_iter_dst, dst);
|
2017-06-12 18:40:14 +02:00
|
|
|
are_equal = TRUE;
|
|
|
|
|
while (TRUE) {
|
|
|
|
|
gboolean has;
|
2017-07-07 23:34:41 +02:00
|
|
|
const NMPlatformIP4Route *r_src = NULL;
|
|
|
|
|
const NMPlatformIP4Route *r_dst = NULL;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-07-23 12:19:15 +02:00
|
|
|
has = nm_platform_dedup_multi_iter_next_ip4_route(&ipconf_iter_src, &r_src);
|
|
|
|
|
if (has != nm_platform_dedup_multi_iter_next_ip4_route(&ipconf_iter_dst, &r_dst)) {
|
2017-06-12 18:40:14 +02:00
|
|
|
are_equal = FALSE;
|
|
|
|
|
has_relevant_changes = TRUE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (!has)
|
|
|
|
|
break;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-07-26 10:50:23 +02:00
|
|
|
if (nm_platform_ip4_route_cmp_full(r_src, r_dst) != 0) {
|
2017-06-12 18:40:14 +02:00
|
|
|
are_equal = FALSE;
|
2017-09-11 21:41:57 +02:00
|
|
|
if (r_src->plen != r_dst->plen
|
|
|
|
|
|| !nm_utils_ip4_address_same_prefix(r_src->network, r_dst->network, r_src->plen)
|
2017-07-15 11:47:48 +02:00
|
|
|
|| r_src->gateway != r_dst->gateway || r_src->metric != r_dst->metric) {
|
2017-06-12 18:40:14 +02:00
|
|
|
has_relevant_changes = TRUE;
|
|
|
|
|
break;
|
2013-09-06 11:02:03 +02:00
|
|
|
}
|
|
|
|
|
}
|
2017-06-12 18:40:14 +02:00
|
|
|
}
|
2013-09-06 11:02:03 +02:00
|
|
|
if (!are_equal) {
|
|
|
|
|
has_minor_changes = TRUE;
|
2017-08-31 13:39:04 +02:00
|
|
|
new_best_default_route = NULL;
|
2017-06-12 18:40:14 +02:00
|
|
|
nm_dedup_multi_index_dirty_set_idx(dst_priv->multi_idx, &dst_priv->idx_ip4_routes);
|
2017-07-16 19:18:51 +02:00
|
|
|
nm_dedup_multi_iter_for_each (&ipconf_iter_src, head_entry_src) {
|
2017-08-31 13:39:04 +02:00
|
|
|
const NMPObject *o = ipconf_iter_src.current->obj;
|
|
|
|
|
const NMPObject *obj_new;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-08-31 13:01:19 +02:00
|
|
|
_nm_ip_config_add_obj(dst_priv->multi_idx,
|
|
|
|
|
&dst_priv->idx_ip4_routes_,
|
|
|
|
|
dst_priv->ifindex,
|
2017-08-31 13:39:04 +02:00
|
|
|
o,
|
2017-08-31 13:01:19 +02:00
|
|
|
NULL,
|
|
|
|
|
FALSE,
|
2017-08-30 19:05:38 +02:00
|
|
|
TRUE,
|
2017-09-05 10:36:50 +02:00
|
|
|
NULL,
|
2017-08-31 13:39:04 +02:00
|
|
|
&obj_new);
|
|
|
|
|
new_best_default_route =
|
|
|
|
|
_nm_ip_config_best_default_route_find_better(new_best_default_route, obj_new);
|
2017-06-12 18:40:14 +02:00
|
|
|
}
|
|
|
|
|
nm_dedup_multi_index_dirty_remove_idx(dst_priv->multi_idx,
|
|
|
|
|
&dst_priv->idx_ip4_routes,
|
|
|
|
|
FALSE);
|
2020-07-21 17:49:23 +02:00
|
|
|
if (nmp_object_ref_set(&dst_priv->best_default_route, new_best_default_route))
|
2017-10-04 15:21:21 +02:00
|
|
|
_notify(dst, PROP_GATEWAY);
|
2017-07-25 14:23:10 +02:00
|
|
|
_notify_routes(dst);
|
2013-09-06 11:02:03 +02:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-09-06 11:02:03 +02:00
|
|
|
/* nameservers */
|
|
|
|
|
num = nm_ip4_config_get_num_nameservers(src);
|
|
|
|
|
are_equal = num == nm_ip4_config_get_num_nameservers(dst);
|
|
|
|
|
if (are_equal) {
|
|
|
|
|
for (i = 0; i < num; i++) {
|
|
|
|
|
if (nm_ip4_config_get_nameserver(src, i) != nm_ip4_config_get_nameserver(dst, i)) {
|
|
|
|
|
are_equal = FALSE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
|
|
|
|
}
|
2013-09-06 11:02:03 +02:00
|
|
|
if (!are_equal) {
|
|
|
|
|
nm_ip4_config_reset_nameservers(dst);
|
|
|
|
|
for (i = 0; i < num; i++)
|
|
|
|
|
nm_ip4_config_add_nameserver(dst, nm_ip4_config_get_nameserver(src, i));
|
|
|
|
|
has_relevant_changes = TRUE;
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-09-06 11:02:03 +02:00
|
|
|
/* domains */
|
|
|
|
|
num = nm_ip4_config_get_num_domains(src);
|
|
|
|
|
are_equal = num == nm_ip4_config_get_num_domains(dst);
|
|
|
|
|
if (are_equal) {
|
|
|
|
|
for (i = 0; i < num; i++) {
|
|
|
|
|
if (g_strcmp0(nm_ip4_config_get_domain(src, i), nm_ip4_config_get_domain(dst, i))) {
|
|
|
|
|
are_equal = FALSE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
|
|
|
|
}
|
2013-09-06 11:02:03 +02:00
|
|
|
if (!are_equal) {
|
|
|
|
|
nm_ip4_config_reset_domains(dst);
|
|
|
|
|
for (i = 0; i < num; i++)
|
|
|
|
|
nm_ip4_config_add_domain(dst, nm_ip4_config_get_domain(src, i));
|
|
|
|
|
has_relevant_changes = TRUE;
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-09-06 11:02:03 +02:00
|
|
|
/* dns searches */
|
|
|
|
|
num = nm_ip4_config_get_num_searches(src);
|
|
|
|
|
are_equal = num == nm_ip4_config_get_num_searches(dst);
|
|
|
|
|
if (are_equal) {
|
|
|
|
|
for (i = 0; i < num; i++) {
|
|
|
|
|
if (g_strcmp0(nm_ip4_config_get_search(src, i), nm_ip4_config_get_search(dst, i))) {
|
|
|
|
|
are_equal = FALSE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
2013-09-06 11:02:03 +02:00
|
|
|
if (!are_equal) {
|
|
|
|
|
nm_ip4_config_reset_searches(dst);
|
|
|
|
|
for (i = 0; i < num; i++)
|
|
|
|
|
nm_ip4_config_add_search(dst, nm_ip4_config_get_search(src, i));
|
|
|
|
|
has_relevant_changes = TRUE;
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2015-03-26 09:23:12 +01:00
|
|
|
/* dns options */
|
|
|
|
|
num = nm_ip4_config_get_num_dns_options(src);
|
|
|
|
|
are_equal = num == nm_ip4_config_get_num_dns_options(dst);
|
|
|
|
|
if (are_equal) {
|
|
|
|
|
for (i = 0; i < num; i++) {
|
|
|
|
|
if (g_strcmp0(nm_ip4_config_get_dns_option(src, i),
|
|
|
|
|
nm_ip4_config_get_dns_option(dst, i))) {
|
|
|
|
|
are_equal = FALSE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
2015-03-26 09:23:12 +01:00
|
|
|
if (!are_equal) {
|
|
|
|
|
nm_ip4_config_reset_dns_options(dst);
|
|
|
|
|
for (i = 0; i < num; i++)
|
|
|
|
|
nm_ip4_config_add_dns_option(dst, nm_ip4_config_get_dns_option(src, i));
|
|
|
|
|
has_relevant_changes = TRUE;
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2018-08-31 17:02:21 +02:00
|
|
|
if (src_priv->mdns != dst_priv->mdns) {
|
|
|
|
|
dst_priv->mdns = src_priv->mdns;
|
|
|
|
|
has_relevant_changes = TRUE;
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2018-08-31 17:02:21 +02:00
|
|
|
if (src_priv->llmnr != dst_priv->llmnr) {
|
|
|
|
|
dst_priv->llmnr = src_priv->llmnr;
|
|
|
|
|
has_relevant_changes = TRUE;
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2016-04-23 15:57:14 +02:00
|
|
|
/* DNS priority */
|
|
|
|
|
if (src_priv->dns_priority != dst_priv->dns_priority) {
|
|
|
|
|
nm_ip4_config_set_dns_priority(dst, src_priv->dns_priority);
|
2016-05-30 14:37:22 +02:00
|
|
|
has_minor_changes = TRUE;
|
2016-04-23 15:57:14 +02:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-09-06 11:02:03 +02:00
|
|
|
/* nis */
|
|
|
|
|
num = nm_ip4_config_get_num_nis_servers(src);
|
|
|
|
|
are_equal = num == nm_ip4_config_get_num_nis_servers(dst);
|
|
|
|
|
if (are_equal) {
|
|
|
|
|
for (i = 0; i < num; i++) {
|
|
|
|
|
if (nm_ip4_config_get_nis_server(src, i) != nm_ip4_config_get_nis_server(dst, i)) {
|
|
|
|
|
are_equal = FALSE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
2013-09-06 11:02:03 +02:00
|
|
|
if (!are_equal) {
|
|
|
|
|
nm_ip4_config_reset_nis_servers(dst);
|
|
|
|
|
for (i = 0; i < num; i++)
|
|
|
|
|
nm_ip4_config_add_nis_server(dst, nm_ip4_config_get_nis_server(src, i));
|
|
|
|
|
has_relevant_changes = TRUE;
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-09-06 11:02:03 +02:00
|
|
|
/* nis_domain */
|
|
|
|
|
if (g_strcmp0(src_priv->nis_domain, dst_priv->nis_domain)) {
|
|
|
|
|
nm_ip4_config_set_nis_domain(dst, src_priv->nis_domain);
|
|
|
|
|
has_relevant_changes = TRUE;
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-09-06 11:02:03 +02:00
|
|
|
/* wins */
|
|
|
|
|
num = nm_ip4_config_get_num_wins(src);
|
|
|
|
|
are_equal = num == nm_ip4_config_get_num_wins(dst);
|
|
|
|
|
if (are_equal) {
|
|
|
|
|
for (i = 0; i < num; i++) {
|
|
|
|
|
if (nm_ip4_config_get_wins(src, i) != nm_ip4_config_get_wins(dst, i)) {
|
|
|
|
|
are_equal = FALSE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
2013-09-06 11:02:03 +02:00
|
|
|
if (!are_equal) {
|
|
|
|
|
nm_ip4_config_reset_wins(dst);
|
|
|
|
|
for (i = 0; i < num; i++)
|
|
|
|
|
nm_ip4_config_add_wins(dst, nm_ip4_config_get_wins(src, i));
|
|
|
|
|
has_relevant_changes = TRUE;
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-09-06 11:02:03 +02:00
|
|
|
/* mtu */
|
2017-01-15 12:57:50 +01:00
|
|
|
if (src_priv->mtu != dst_priv->mtu || src_priv->mtu_source != dst_priv->mtu_source) {
|
2014-10-09 18:51:11 +02:00
|
|
|
nm_ip4_config_set_mtu(dst, src_priv->mtu, src_priv->mtu_source);
|
2013-09-06 11:02:03 +02:00
|
|
|
has_minor_changes = TRUE;
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2015-04-30 18:11:16 +02:00
|
|
|
/* metered */
|
|
|
|
|
if (src_priv->metered != dst_priv->metered) {
|
|
|
|
|
dst_priv->metered = src_priv->metered;
|
|
|
|
|
has_minor_changes = TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-29 12:06:11 +02:00
|
|
|
/* never default */
|
|
|
|
|
if (src_priv->never_default != dst_priv->never_default) {
|
|
|
|
|
dst_priv->never_default = src_priv->never_default;
|
|
|
|
|
has_minor_changes = TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-10 20:51:17 +02:00
|
|
|
#if NM_MORE_ASSERTS
|
2013-09-06 11:02:03 +02:00
|
|
|
/* config_equal does not compare *all* the fields, therefore, we might have has_minor_changes
|
|
|
|
|
* regardless of config_equal. But config_equal must correspond to has_relevant_changes. */
|
2015-10-10 20:51:17 +02:00
|
|
|
nm_assert(config_equal == !has_relevant_changes);
|
|
|
|
|
#endif
|
2013-09-06 11:02:03 +02:00
|
|
|
|
2013-09-06 11:56:41 +02:00
|
|
|
g_object_thaw_notify(G_OBJECT(dst));
|
|
|
|
|
|
2013-09-06 11:02:03 +02:00
|
|
|
if (relevant_changes)
|
|
|
|
|
*relevant_changes = has_relevant_changes;
|
|
|
|
|
|
|
|
|
|
return has_relevant_changes || has_minor_changes;
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-01 16:10:15 -05:00
|
|
|
void
|
2018-09-21 18:30:49 +02:00
|
|
|
nm_ip_config_dump(const NMIPConfig *self, const char *detail, NMLogLevel level, NMLogDomain domain)
|
2013-08-01 16:10:15 -05:00
|
|
|
{
|
2017-06-12 18:40:14 +02:00
|
|
|
NMDedupMultiIter ipconf_iter;
|
2018-09-21 18:30:49 +02:00
|
|
|
const NMPlatformIP4Address *addr4;
|
|
|
|
|
const NMPlatformIP6Address *addr6;
|
|
|
|
|
const NMPlatformIP4Route * route4;
|
|
|
|
|
const NMPlatformIP6Route * route6;
|
|
|
|
|
const NMIP4Config * ip4;
|
|
|
|
|
const NMIP6Config * ip6;
|
|
|
|
|
int addr_family = AF_UNSPEC;
|
|
|
|
|
char addr_family_char = '?';
|
|
|
|
|
const char * path;
|
|
|
|
|
gconstpointer ptr;
|
|
|
|
|
guint i;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2018-09-21 18:30:49 +02:00
|
|
|
if (self) {
|
|
|
|
|
addr_family = nm_ip_config_get_addr_family(self);
|
|
|
|
|
addr_family_char = nm_utils_addr_family_to_char(addr_family);
|
2016-01-12 17:58:18 +01:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2018-09-21 18:30:49 +02:00
|
|
|
nm_log(level, domain, NULL, NULL, "---- NMIP%cConfig %p (%s)", addr_family_char, self, detail);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2018-09-21 18:30:49 +02:00
|
|
|
if (!self)
|
2020-09-28 16:03:33 +02:00
|
|
|
return;
|
|
|
|
|
|
2018-09-21 18:30:49 +02:00
|
|
|
path = nm_dbus_object_get_path(NM_DBUS_OBJECT(self));
|
|
|
|
|
if (path)
|
|
|
|
|
nm_log(level, domain, NULL, NULL, " path : %s", path);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2018-09-21 18:30:49 +02:00
|
|
|
if (addr_family == AF_INET) {
|
|
|
|
|
ip4 = NM_IP4_CONFIG(self);
|
|
|
|
|
nm_ip_config_iter_ip4_address_for_each (&ipconf_iter, ip4, &addr4) {
|
|
|
|
|
nm_log(level,
|
|
|
|
|
domain,
|
|
|
|
|
NULL,
|
|
|
|
|
NULL,
|
|
|
|
|
" address : %s",
|
|
|
|
|
nm_platform_ip4_address_to_string(addr4, NULL, 0));
|
|
|
|
|
}
|
|
|
|
|
nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, ip4, &route4) {
|
|
|
|
|
nm_log(level,
|
|
|
|
|
domain,
|
|
|
|
|
NULL,
|
|
|
|
|
NULL,
|
|
|
|
|
" route : %s",
|
|
|
|
|
nm_platform_ip4_route_to_string(route4, NULL, 0));
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
ip6 = NM_IP6_CONFIG(self);
|
|
|
|
|
nm_ip_config_iter_ip6_address_for_each (&ipconf_iter, ip6, &addr6) {
|
|
|
|
|
nm_log(level,
|
|
|
|
|
domain,
|
|
|
|
|
NULL,
|
|
|
|
|
NULL,
|
|
|
|
|
" address : %s",
|
|
|
|
|
nm_platform_ip6_address_to_string(addr6, NULL, 0));
|
|
|
|
|
}
|
|
|
|
|
nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, ip6, &route6) {
|
|
|
|
|
nm_log(level,
|
|
|
|
|
domain,
|
|
|
|
|
NULL,
|
|
|
|
|
NULL,
|
|
|
|
|
" route : %s",
|
|
|
|
|
nm_platform_ip6_route_to_string(route6, NULL, 0));
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
2018-09-21 18:30:49 +02:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2018-09-21 18:30:49 +02:00
|
|
|
for (i = 0; i < nm_ip_config_get_num_nameservers(self); i++) {
|
2018-11-26 16:49:51 +01:00
|
|
|
char buf[NM_UTILS_INET_ADDRSTRLEN];
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2018-09-21 18:30:49 +02:00
|
|
|
ptr = nm_ip_config_get_nameserver(self, i);
|
|
|
|
|
nm_log(level,
|
|
|
|
|
domain,
|
|
|
|
|
NULL,
|
|
|
|
|
NULL,
|
|
|
|
|
" dns : %s",
|
2018-11-26 16:49:51 +01:00
|
|
|
nm_utils_inet_ntop(addr_family, ptr, buf));
|
2018-09-21 18:30:49 +02:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2018-09-21 18:30:49 +02:00
|
|
|
for (i = 0; i < nm_ip_config_get_num_domains(self); i++)
|
|
|
|
|
nm_log(level, domain, NULL, NULL, " domain : %s", nm_ip_config_get_domain(self, i));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2018-09-21 18:30:49 +02:00
|
|
|
for (i = 0; i < nm_ip_config_get_num_searches(self); i++)
|
|
|
|
|
nm_log(level, domain, NULL, NULL, " search : %s", nm_ip_config_get_search(self, i));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2018-09-21 18:30:49 +02:00
|
|
|
for (i = 0; i < nm_ip_config_get_num_dns_options(self); i++)
|
|
|
|
|
nm_log(level, domain, NULL, NULL, "dns-option: %s", nm_ip_config_get_dns_option(self, i));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2018-09-21 18:30:49 +02:00
|
|
|
nm_log(level, domain, NULL, NULL, " dns-prio : %d", nm_ip_config_get_dns_priority(self));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2018-09-21 18:30:49 +02:00
|
|
|
if (addr_family == AF_INET) {
|
|
|
|
|
ip4 = NM_IP4_CONFIG(self);
|
|
|
|
|
nm_log(level,
|
|
|
|
|
domain,
|
|
|
|
|
NULL,
|
|
|
|
|
NULL,
|
|
|
|
|
" mtu : %" G_GUINT32_FORMAT " (source: %d)",
|
|
|
|
|
nm_ip4_config_get_mtu(ip4),
|
|
|
|
|
(int) nm_ip4_config_get_mtu_source(ip4));
|
|
|
|
|
nm_log(level, domain, NULL, NULL, " metered : %d", (int) nm_ip4_config_get_metered(ip4));
|
2013-08-01 16:10:15 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2013-07-12 11:33:52 +02:00
|
|
|
|
|
|
|
|
void
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_reset_addresses(NMIP4Config *self)
|
2005-04-15 15:43:42 +00:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2005-04-15 15:43:42 +00:00
|
|
|
|
2017-07-07 23:34:41 +02:00
|
|
|
if (nm_dedup_multi_index_remove_idx(priv->multi_idx, &priv->idx_ip4_addresses) > 0)
|
|
|
|
|
_notify_addresses(self);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
_add_address(NMIP4Config *self, const NMPObject *obj_new, const NMPlatformIP4Address *new)
|
|
|
|
|
{
|
|
|
|
|
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
|
|
|
|
|
|
|
|
|
if (_nm_ip_config_add_obj(priv->multi_idx,
|
|
|
|
|
&priv->idx_ip4_addresses_,
|
|
|
|
|
priv->ifindex,
|
|
|
|
|
obj_new,
|
2017-08-16 14:38:39 +02:00
|
|
|
(const NMPlatformObject *) new,
|
|
|
|
|
TRUE,
|
2017-08-30 19:05:38 +02:00
|
|
|
FALSE,
|
2017-09-05 10:36:50 +02:00
|
|
|
NULL,
|
2017-08-30 19:05:38 +02:00
|
|
|
NULL))
|
2017-07-07 23:34:41 +02:00
|
|
|
_notify_addresses(self);
|
2005-04-15 15:43:42 +00:00
|
|
|
}
|
|
|
|
|
|
2014-01-06 14:14:14 -06:00
|
|
|
/**
|
|
|
|
|
* nm_ip4_config_add_address:
|
2017-07-10 14:03:44 +02:00
|
|
|
* @self: the #NMIP4Config
|
|
|
|
|
* @new: the new address to add to @self
|
2014-01-06 14:14:14 -06:00
|
|
|
*
|
2017-07-10 14:03:44 +02:00
|
|
|
* Adds the new address to @self. If an address with the same basic properties
|
|
|
|
|
* (address, prefix) already exists in @self, it is overwritten with the
|
2014-01-06 14:14:14 -06:00
|
|
|
* lifetime and preferred of @new. The source is also overwritten by the source
|
|
|
|
|
* from @new if that source is higher priority.
|
|
|
|
|
*/
|
2013-07-12 11:33:52 +02:00
|
|
|
void
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_add_address(NMIP4Config *self, const NMPlatformIP4Address *new)
|
2013-06-11 17:05:49 -05:00
|
|
|
{
|
2017-07-07 23:34:41 +02:00
|
|
|
g_return_if_fail(self);
|
|
|
|
|
g_return_if_fail(new);
|
2018-12-14 17:04:21 +01:00
|
|
|
g_return_if_fail(new->plen <= 32);
|
2017-07-07 23:34:41 +02:00
|
|
|
g_return_if_fail(NM_IP4_CONFIG_GET_PRIVATE(self)->ifindex > 0);
|
2013-06-11 17:05:49 -05:00
|
|
|
|
2017-07-07 23:34:41 +02:00
|
|
|
_add_address(self, NULL, new);
|
2005-04-15 15:43:42 +00:00
|
|
|
}
|
|
|
|
|
|
2013-08-01 14:04:35 -05:00
|
|
|
void
|
2017-09-05 10:31:56 +02:00
|
|
|
_nmtst_ip4_config_del_address(NMIP4Config *self, guint i)
|
2013-08-01 14:04:35 -05:00
|
|
|
{
|
2017-07-07 23:34:41 +02:00
|
|
|
const NMPlatformIP4Address *a;
|
2013-08-01 14:04:35 -05:00
|
|
|
|
2017-09-05 10:31:56 +02:00
|
|
|
a = _nmtst_ip4_config_get_address(self, i);
|
2017-08-31 13:39:04 +02:00
|
|
|
if (!nm_ip4_config_nmpobj_remove(self, NMP_OBJECT_UP_CAST(a)))
|
|
|
|
|
g_assert_not_reached();
|
2013-08-01 14:04:35 -05:00
|
|
|
}
|
|
|
|
|
|
2013-07-12 11:33:52 +02:00
|
|
|
guint
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_get_num_addresses(const NMIP4Config *self)
|
2005-04-15 15:43:42 +00:00
|
|
|
{
|
2017-07-07 23:34:41 +02:00
|
|
|
const NMDedupMultiHeadEntry *head_entry;
|
2005-04-15 15:43:42 +00:00
|
|
|
|
2017-07-07 23:34:41 +02:00
|
|
|
head_entry = nm_ip4_config_lookup_addresses(self);
|
|
|
|
|
return head_entry ? head_entry->len : 0;
|
2005-04-15 15:43:42 +00:00
|
|
|
}
|
|
|
|
|
|
2013-06-29 13:33:36 +02:00
|
|
|
const NMPlatformIP4Address *
|
2017-07-07 23:34:41 +02:00
|
|
|
nm_ip4_config_get_first_address(const NMIP4Config *self)
|
2005-04-15 15:43:42 +00:00
|
|
|
{
|
2017-07-07 23:34:41 +02:00
|
|
|
NMDedupMultiIter iter;
|
|
|
|
|
const NMPlatformIP4Address *a = NULL;
|
2008-12-19 17:01:06 -05:00
|
|
|
|
2017-07-07 23:34:41 +02:00
|
|
|
nm_ip_config_iter_ip4_address_for_each (&iter, self, &a)
|
|
|
|
|
return a;
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const NMPlatformIP4Address *
|
2017-09-05 10:31:56 +02:00
|
|
|
_nmtst_ip4_config_get_address(const NMIP4Config *self, guint i)
|
2017-07-07 23:34:41 +02:00
|
|
|
{
|
2019-02-03 11:15:11 +01:00
|
|
|
NMDedupMultiIter iter = {};
|
2017-07-07 23:34:41 +02:00
|
|
|
const NMPlatformIP4Address *a = NULL;
|
|
|
|
|
guint j;
|
|
|
|
|
|
|
|
|
|
j = 0;
|
|
|
|
|
nm_ip_config_iter_ip4_address_for_each (&iter, self, &a) {
|
|
|
|
|
if (i == j)
|
|
|
|
|
return a;
|
|
|
|
|
j++;
|
|
|
|
|
}
|
|
|
|
|
g_return_val_if_reached(NULL);
|
2005-04-15 15:43:42 +00:00
|
|
|
}
|
|
|
|
|
|
2013-11-02 10:20:03 -05:00
|
|
|
gboolean
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_address_exists(const NMIP4Config *self, const NMPlatformIP4Address *needle)
|
2013-11-02 10:20:03 -05:00
|
|
|
{
|
2017-07-07 23:34:41 +02:00
|
|
|
const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
|
|
|
|
NMPObject obj_stack;
|
|
|
|
|
|
|
|
|
|
nmp_object_stackinit_id_ip4_address(&obj_stack,
|
|
|
|
|
priv->ifindex,
|
|
|
|
|
needle->address,
|
|
|
|
|
needle->plen,
|
|
|
|
|
needle->peer_address);
|
|
|
|
|
return !!nm_dedup_multi_index_lookup_obj(priv->multi_idx, &priv->idx_ip4_addresses, &obj_stack);
|
2013-11-02 10:20:03 -05:00
|
|
|
}
|
|
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2005-04-15 15:43:42 +00:00
|
|
|
|
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-14 14:18:53 +02:00
|
|
|
static const NMDedupMultiEntry *
|
|
|
|
|
_lookup_route(const NMIP4Config *self, const NMPObject *needle, NMPlatformIPRouteCmpType cmp_type)
|
|
|
|
|
{
|
|
|
|
|
const NMIP4ConfigPrivate *priv;
|
|
|
|
|
|
|
|
|
|
nm_assert(NM_IS_IP4_CONFIG(self));
|
|
|
|
|
nm_assert(NMP_OBJECT_GET_TYPE(needle) == NMP_OBJECT_TYPE_IP4_ROUTE);
|
|
|
|
|
|
|
|
|
|
priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
|
|
|
|
|
|
|
|
|
return _nm_ip_config_lookup_ip_route(priv->multi_idx, &priv->idx_ip4_routes_, needle, cmp_type);
|
|
|
|
|
}
|
|
|
|
|
|
2013-07-12 11:33:52 +02:00
|
|
|
void
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_reset_routes(NMIP4Config *self)
|
2005-04-15 15:43:42 +00:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2005-04-15 15:43:42 +00:00
|
|
|
|
2017-06-12 18:40:14 +02:00
|
|
|
if (nm_dedup_multi_index_remove_idx(priv->multi_idx, &priv->idx_ip4_routes) > 0) {
|
2017-10-04 15:21:21 +02:00
|
|
|
if (nm_clear_nmp_object(&priv->best_default_route))
|
|
|
|
|
_notify(self, PROP_GATEWAY);
|
2017-07-07 23:34:41 +02:00
|
|
|
_notify_routes(self);
|
2017-08-31 13:39:04 +02:00
|
|
|
}
|
2005-04-15 15:43:42 +00:00
|
|
|
}
|
|
|
|
|
|
2017-06-12 18:40:14 +02:00
|
|
|
static void
|
2017-09-05 10:36:50 +02:00
|
|
|
_add_route(NMIP4Config * self,
|
|
|
|
|
const NMPObject *obj_new,
|
|
|
|
|
const NMPlatformIP4Route *new,
|
|
|
|
|
const NMPObject **out_obj_new)
|
2017-06-12 18:40:14 +02:00
|
|
|
{
|
2017-07-07 23:34:41 +02:00
|
|
|
NMIP4ConfigPrivate * priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2017-08-31 13:39:04 +02:00
|
|
|
nm_auto_nmpobj const NMPObject *obj_old = NULL;
|
2017-09-05 10:36:50 +02:00
|
|
|
const NMPObject * obj_new_2;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-07-19 11:30:13 +02:00
|
|
|
nm_assert((!new) != (!obj_new));
|
|
|
|
|
nm_assert(!new || _route_valid(new));
|
|
|
|
|
nm_assert(!obj_new || _route_valid(NMP_OBJECT_CAST_IP4_ROUTE(obj_new)));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-07-07 23:34:41 +02:00
|
|
|
if (_nm_ip_config_add_obj(priv->multi_idx,
|
|
|
|
|
&priv->idx_ip4_routes_,
|
|
|
|
|
priv->ifindex,
|
|
|
|
|
obj_new,
|
2017-08-16 14:38:39 +02:00
|
|
|
(const NMPlatformObject *) new,
|
|
|
|
|
TRUE,
|
2017-08-30 19:05:38 +02:00
|
|
|
FALSE,
|
2017-08-31 13:39:04 +02:00
|
|
|
&obj_old,
|
2017-09-05 10:36:50 +02:00
|
|
|
&obj_new_2)) {
|
2017-10-04 15:21:21 +02:00
|
|
|
gboolean changed_default_route = FALSE;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-08-31 13:39:04 +02:00
|
|
|
if (priv->best_default_route == obj_old && obj_old != obj_new_2) {
|
2017-10-04 15:21:21 +02:00
|
|
|
changed_default_route = TRUE;
|
2017-08-31 13:39:04 +02:00
|
|
|
nm_clear_nmp_object(&priv->best_default_route);
|
2017-10-04 15:21:21 +02:00
|
|
|
}
|
2017-09-05 10:36:50 +02:00
|
|
|
NM_SET_OUT(out_obj_new, nmp_object_ref(obj_new_2));
|
2017-10-04 15:21:21 +02:00
|
|
|
if (_nm_ip_config_best_default_route_merge(&priv->best_default_route, obj_new_2))
|
|
|
|
|
changed_default_route = TRUE;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-10-04 15:21:21 +02:00
|
|
|
if (changed_default_route)
|
|
|
|
|
_notify(self, PROP_GATEWAY);
|
2017-07-07 23:34:41 +02:00
|
|
|
_notify_routes(self);
|
2017-09-05 10:36:50 +02:00
|
|
|
} else
|
|
|
|
|
NM_SET_OUT(out_obj_new, nmp_object_ref(obj_new_2));
|
2017-06-12 18:40:14 +02:00
|
|
|
}
|
|
|
|
|
|
2014-01-06 14:14:14 -06:00
|
|
|
/**
|
|
|
|
|
* nm_ip4_config_add_route:
|
2017-07-10 14:03:44 +02:00
|
|
|
* @self: the #NMIP4Config
|
|
|
|
|
* @new: the new route to add to @self
|
2019-03-06 20:04:50 +01:00
|
|
|
* @out_obj_new: (allow-none) (out): the added route object. Must be unrefed
|
2017-09-05 10:36:50 +02:00
|
|
|
* by caller.
|
2014-01-06 14:14:14 -06:00
|
|
|
*
|
2017-07-10 14:03:44 +02:00
|
|
|
* Adds the new route to @self. If a route with the same basic properties
|
|
|
|
|
* (network, prefix) already exists in @self, it is overwritten including the
|
2014-01-06 14:14:14 -06:00
|
|
|
* gateway and metric of @new. The source is also overwritten by the source
|
|
|
|
|
* from @new if that source is higher priority.
|
|
|
|
|
*/
|
2013-07-12 11:33:52 +02:00
|
|
|
void
|
2017-09-05 10:36:50 +02:00
|
|
|
nm_ip4_config_add_route(NMIP4Config *self,
|
|
|
|
|
const NMPlatformIP4Route *new,
|
|
|
|
|
const NMPObject **out_obj_new)
|
2008-12-19 17:01:06 -05:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
g_return_if_fail(self);
|
2017-06-12 18:40:14 +02:00
|
|
|
g_return_if_fail(new);
|
2017-08-31 13:39:04 +02:00
|
|
|
g_return_if_fail(new->plen <= 32);
|
2017-07-10 14:03:44 +02:00
|
|
|
g_return_if_fail(NM_IP4_CONFIG_GET_PRIVATE(self)->ifindex > 0);
|
2013-07-15 17:56:46 -05:00
|
|
|
|
2017-09-05 10:36:50 +02:00
|
|
|
_add_route(self, NULL, new, out_obj_new);
|
2008-12-19 17:01:06 -05:00
|
|
|
}
|
|
|
|
|
|
2013-08-01 14:04:35 -05:00
|
|
|
void
|
2017-09-05 10:31:56 +02:00
|
|
|
_nmtst_ip4_config_del_route(NMIP4Config *self, guint i)
|
2013-08-01 14:04:35 -05:00
|
|
|
{
|
2017-06-12 18:40:14 +02:00
|
|
|
const NMPlatformIP4Route *r;
|
2013-07-31 23:07:32 +02:00
|
|
|
|
2017-09-05 10:31:56 +02:00
|
|
|
r = _nmtst_ip4_config_get_route(self, i);
|
2017-08-31 13:39:04 +02:00
|
|
|
if (!nm_ip4_config_nmpobj_remove(self, NMP_OBJECT_UP_CAST(r)))
|
|
|
|
|
g_assert_not_reached();
|
2013-08-01 14:04:35 -05:00
|
|
|
}
|
|
|
|
|
|
2013-07-12 11:33:52 +02:00
|
|
|
guint
|
2017-06-12 18:40:14 +02:00
|
|
|
nm_ip4_config_get_num_routes(const NMIP4Config *self)
|
2008-12-19 17:01:06 -05:00
|
|
|
{
|
2017-06-12 18:40:14 +02:00
|
|
|
const NMDedupMultiHeadEntry *head_entry;
|
2008-12-19 17:01:06 -05:00
|
|
|
|
2017-07-07 23:34:41 +02:00
|
|
|
head_entry = nm_ip4_config_lookup_routes(self);
|
2017-09-12 10:07:39 +02:00
|
|
|
nm_assert(!head_entry || head_entry->len == c_list_length(&head_entry->lst_entries_head));
|
2017-06-12 18:40:14 +02:00
|
|
|
return head_entry ? head_entry->len : 0;
|
2008-12-19 17:01:06 -05:00
|
|
|
}
|
|
|
|
|
|
2013-09-24 18:19:18 +02:00
|
|
|
const NMPlatformIP4Route *
|
2017-09-05 10:31:56 +02:00
|
|
|
_nmtst_ip4_config_get_route(const NMIP4Config *self, guint i)
|
2017-06-12 18:40:14 +02:00
|
|
|
{
|
2017-07-07 23:34:41 +02:00
|
|
|
NMDedupMultiIter iter;
|
|
|
|
|
const NMPlatformIP4Route *r = NULL;
|
2017-06-12 18:40:14 +02:00
|
|
|
guint j;
|
|
|
|
|
|
2017-07-07 23:34:41 +02:00
|
|
|
j = 0;
|
|
|
|
|
nm_ip_config_iter_ip4_route_for_each (&iter, self, &r) {
|
|
|
|
|
if (i == j)
|
|
|
|
|
return r;
|
|
|
|
|
j++;
|
2017-06-12 18:40:14 +02:00
|
|
|
}
|
|
|
|
|
g_return_val_if_reached(NULL);
|
2008-12-19 17:01:06 -05:00
|
|
|
}
|
|
|
|
|
|
2014-08-28 23:36:45 +02:00
|
|
|
const NMPlatformIP4Route *
|
2017-10-04 15:21:21 +02:00
|
|
|
nm_ip4_config_get_direct_route_for_host(const NMIP4Config *self,
|
|
|
|
|
in_addr_t host,
|
|
|
|
|
guint32 route_table)
|
2014-08-28 23:36:45 +02:00
|
|
|
{
|
2017-06-12 18:40:14 +02:00
|
|
|
const NMPlatformIP4Route *best_route = NULL;
|
|
|
|
|
const NMPlatformIP4Route *item;
|
|
|
|
|
NMDedupMultiIter ipconf_iter;
|
2014-08-28 23:36:45 +02:00
|
|
|
|
|
|
|
|
g_return_val_if_fail(host, NULL);
|
|
|
|
|
|
2017-07-07 23:34:41 +02:00
|
|
|
nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, self, &item) {
|
2014-08-28 23:36:45 +02:00
|
|
|
if (item->gateway != 0)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (best_route && best_route->plen > item->plen)
|
|
|
|
|
continue;
|
|
|
|
|
|
2017-10-04 15:21:21 +02:00
|
|
|
if (nm_platform_route_table_uncoerce(item->table_coerced, TRUE) != route_table)
|
|
|
|
|
continue;
|
|
|
|
|
|
2014-08-28 23:36:45 +02:00
|
|
|
if (nm_utils_ip4_address_clear_host_address(host, item->plen)
|
|
|
|
|
!= nm_utils_ip4_address_clear_host_address(item->network, item->plen))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (best_route && best_route->metric <= item->metric)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
best_route = item;
|
|
|
|
|
}
|
|
|
|
|
return best_route;
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2013-07-12 11:33:52 +02:00
|
|
|
|
2008-06-02 08:44:48 +00:00
|
|
|
void
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_reset_nameservers(NMIP4Config *self)
|
2007-11-28 22:38:33 +00:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2007-11-28 22:38:33 +00:00
|
|
|
|
2013-09-06 11:56:41 +02:00
|
|
|
if (priv->nameservers->len != 0) {
|
|
|
|
|
g_array_set_size(priv->nameservers, 0);
|
all: avoid byte ordering issue for IP4Config's Nameservers/WinsServers on D-Bus
Some properties in NetworkManager's D-Bus API are IPv4 addresses
in network byte order (big endian). That is problematic.
It is no problem, when the NetworkManager client runs on the same
host. That is the case with libnm, which does not support to be used
remotely for the time being.
It is a problem for an application that wants to access the D-Bus
interface of NetworkManager remotely. Possibly, such an application
would be implemented in two layers:
- one layer merely remotes D-Bus, without specific knowledge of
NetworkManager's API.
- a higher layer which accesses the remote D-Bus interface of NetworkManager.
Preferably it does so in an agnostic way, regardless of whether it runs
locally or remotely.
When using a D-Bus library, all accesses to 32 bit integers are in
native endianness (regardless of how the integer is actually encoded
on the lower layers). Likewise, D-Bus does not support annotating integer
types in non-native endianness. There is no way to annotate an integer
type "u" to be anything but native order.
That means, when remoting D-Bus at some point the endianness must be
corrected.
But by looking at the D-Bus introspection alone, it is not possible
to know which property need correction and which don't. One would need
to understand the meaning of the properties.
That makes it problematic, because the higher layer of the application,
which knows that the "Nameservers" property is supposed to be in network
order, might not easily know, whether it must correct for endianness.
Deprecate IP4Config properties that are only accessible with a particular
endianness, and add new properties that expose the same data in an
agnostic way.
Note that I added "WinsServerData" to be a plain "as", while
"NameserverData" is of type "aa{sv}". There is no particularly strong
reason for these choices, except that I could imagine that it could be
useful to expose additional information in the future about nameservers
(e.g. are they received via DHCP or manual configuration?). On the other
hand, WINS information likely won't get extended in the future.
Also note, libnm was not modified to use the new D-Bus fields. The
endianness issue is no problem for libnm, so there is little reason to
change it (at this point).
https://bugzilla.redhat.com/show_bug.cgi?id=1153559
https://bugzilla.redhat.com/show_bug.cgi?id=1584584
2018-07-13 20:15:33 +02:00
|
|
|
nm_gobject_notify_together(self, PROP_NAMESERVER_DATA, PROP_NAMESERVERS);
|
2013-09-06 11:56:41 +02:00
|
|
|
}
|
2007-11-28 22:38:33 +00:00
|
|
|
}
|
|
|
|
|
|
2008-06-02 08:44:48 +00:00
|
|
|
void
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_add_nameserver(NMIP4Config *self, guint32 new)
|
2007-11-28 22:38:33 +00:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2013-07-12 11:33:52 +02:00
|
|
|
int i;
|
2007-11-28 22:38:33 +00:00
|
|
|
|
2013-07-15 17:56:46 -05:00
|
|
|
g_return_if_fail(new != 0);
|
|
|
|
|
|
2013-07-12 11:33:52 +02:00
|
|
|
for (i = 0; i < priv->nameservers->len; i++)
|
|
|
|
|
if (new == g_array_index(priv->nameservers, guint32, i))
|
2012-05-14 10:35:39 -04:00
|
|
|
return;
|
|
|
|
|
|
2013-07-12 11:33:52 +02:00
|
|
|
g_array_append_val(priv->nameservers, new);
|
all: avoid byte ordering issue for IP4Config's Nameservers/WinsServers on D-Bus
Some properties in NetworkManager's D-Bus API are IPv4 addresses
in network byte order (big endian). That is problematic.
It is no problem, when the NetworkManager client runs on the same
host. That is the case with libnm, which does not support to be used
remotely for the time being.
It is a problem for an application that wants to access the D-Bus
interface of NetworkManager remotely. Possibly, such an application
would be implemented in two layers:
- one layer merely remotes D-Bus, without specific knowledge of
NetworkManager's API.
- a higher layer which accesses the remote D-Bus interface of NetworkManager.
Preferably it does so in an agnostic way, regardless of whether it runs
locally or remotely.
When using a D-Bus library, all accesses to 32 bit integers are in
native endianness (regardless of how the integer is actually encoded
on the lower layers). Likewise, D-Bus does not support annotating integer
types in non-native endianness. There is no way to annotate an integer
type "u" to be anything but native order.
That means, when remoting D-Bus at some point the endianness must be
corrected.
But by looking at the D-Bus introspection alone, it is not possible
to know which property need correction and which don't. One would need
to understand the meaning of the properties.
That makes it problematic, because the higher layer of the application,
which knows that the "Nameservers" property is supposed to be in network
order, might not easily know, whether it must correct for endianness.
Deprecate IP4Config properties that are only accessible with a particular
endianness, and add new properties that expose the same data in an
agnostic way.
Note that I added "WinsServerData" to be a plain "as", while
"NameserverData" is of type "aa{sv}". There is no particularly strong
reason for these choices, except that I could imagine that it could be
useful to expose additional information in the future about nameservers
(e.g. are they received via DHCP or manual configuration?). On the other
hand, WINS information likely won't get extended in the future.
Also note, libnm was not modified to use the new D-Bus fields. The
endianness issue is no problem for libnm, so there is little reason to
change it (at this point).
https://bugzilla.redhat.com/show_bug.cgi?id=1153559
https://bugzilla.redhat.com/show_bug.cgi?id=1584584
2018-07-13 20:15:33 +02:00
|
|
|
nm_gobject_notify_together(self, PROP_NAMESERVER_DATA, PROP_NAMESERVERS);
|
2008-06-02 08:44:48 +00:00
|
|
|
}
|
|
|
|
|
|
2013-08-01 14:04:35 -05:00
|
|
|
void
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_del_nameserver(NMIP4Config *self, guint i)
|
2013-08-01 14:04:35 -05:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2013-08-01 14:04:35 -05:00
|
|
|
|
|
|
|
|
g_return_if_fail(i < priv->nameservers->len);
|
|
|
|
|
|
|
|
|
|
g_array_remove_index(priv->nameservers, i);
|
all: avoid byte ordering issue for IP4Config's Nameservers/WinsServers on D-Bus
Some properties in NetworkManager's D-Bus API are IPv4 addresses
in network byte order (big endian). That is problematic.
It is no problem, when the NetworkManager client runs on the same
host. That is the case with libnm, which does not support to be used
remotely for the time being.
It is a problem for an application that wants to access the D-Bus
interface of NetworkManager remotely. Possibly, such an application
would be implemented in two layers:
- one layer merely remotes D-Bus, without specific knowledge of
NetworkManager's API.
- a higher layer which accesses the remote D-Bus interface of NetworkManager.
Preferably it does so in an agnostic way, regardless of whether it runs
locally or remotely.
When using a D-Bus library, all accesses to 32 bit integers are in
native endianness (regardless of how the integer is actually encoded
on the lower layers). Likewise, D-Bus does not support annotating integer
types in non-native endianness. There is no way to annotate an integer
type "u" to be anything but native order.
That means, when remoting D-Bus at some point the endianness must be
corrected.
But by looking at the D-Bus introspection alone, it is not possible
to know which property need correction and which don't. One would need
to understand the meaning of the properties.
That makes it problematic, because the higher layer of the application,
which knows that the "Nameservers" property is supposed to be in network
order, might not easily know, whether it must correct for endianness.
Deprecate IP4Config properties that are only accessible with a particular
endianness, and add new properties that expose the same data in an
agnostic way.
Note that I added "WinsServerData" to be a plain "as", while
"NameserverData" is of type "aa{sv}". There is no particularly strong
reason for these choices, except that I could imagine that it could be
useful to expose additional information in the future about nameservers
(e.g. are they received via DHCP or manual configuration?). On the other
hand, WINS information likely won't get extended in the future.
Also note, libnm was not modified to use the new D-Bus fields. The
endianness issue is no problem for libnm, so there is little reason to
change it (at this point).
https://bugzilla.redhat.com/show_bug.cgi?id=1153559
https://bugzilla.redhat.com/show_bug.cgi?id=1584584
2018-07-13 20:15:33 +02:00
|
|
|
nm_gobject_notify_together(self, PROP_NAMESERVER_DATA, PROP_NAMESERVERS);
|
2013-08-01 14:04:35 -05:00
|
|
|
}
|
|
|
|
|
|
2016-10-14 06:08:41 +02:00
|
|
|
guint
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_get_num_nameservers(const NMIP4Config *self)
|
2008-06-02 08:44:48 +00:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2008-08-10 22:37:21 +00:00
|
|
|
|
2013-07-12 11:33:52 +02:00
|
|
|
return priv->nameservers->len;
|
2008-06-02 08:44:48 +00:00
|
|
|
}
|
|
|
|
|
|
2013-07-12 11:33:52 +02:00
|
|
|
guint32
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_get_nameserver(const NMIP4Config *self, guint i)
|
2008-06-02 08:44:48 +00:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2008-06-02 08:44:48 +00:00
|
|
|
|
2013-07-12 11:33:52 +02:00
|
|
|
return g_array_index(priv->nameservers, guint32, i);
|
2007-11-28 22:38:33 +00:00
|
|
|
}
|
|
|
|
|
|
2017-11-08 18:12:36 +01:00
|
|
|
const in_addr_t *
|
|
|
|
|
_nm_ip4_config_get_nameserver(const NMIP4Config *self, guint i)
|
|
|
|
|
{
|
|
|
|
|
const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
|
|
|
|
|
|
|
|
|
return &g_array_index(priv->nameservers, guint32, i);
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2007-11-28 22:38:33 +00:00
|
|
|
|
2018-03-24 09:34:35 +01:00
|
|
|
gboolean
|
|
|
|
|
_nm_ip_config_check_and_add_domain(GPtrArray *array, const char *domain)
|
|
|
|
|
{
|
|
|
|
|
char * copy = NULL;
|
|
|
|
|
size_t len;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail(domain, FALSE);
|
|
|
|
|
g_return_val_if_fail(domain[0] != '\0', FALSE);
|
|
|
|
|
|
|
|
|
|
if (domain[0] == '.' || strstr(domain, ".."))
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
len = strlen(domain);
|
|
|
|
|
if (domain[len - 1] == '.')
|
|
|
|
|
domain = copy = g_strndup(domain, len - 1);
|
|
|
|
|
|
|
|
|
|
if (nm_utils_strv_find_first((char **) array->pdata, array->len, domain) >= 0) {
|
|
|
|
|
g_free(copy);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_ptr_array_add(array, copy ?: g_strdup(domain));
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
2013-07-12 11:33:52 +02:00
|
|
|
void
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_reset_domains(NMIP4Config *self)
|
2008-08-06 22:23:48 +00:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2008-08-06 22:23:48 +00:00
|
|
|
|
2013-09-06 11:56:41 +02:00
|
|
|
if (priv->domains->len != 0) {
|
|
|
|
|
g_ptr_array_set_size(priv->domains, 0);
|
2017-07-10 14:03:44 +02:00
|
|
|
_notify(self, PROP_DOMAINS);
|
2013-09-06 11:56:41 +02:00
|
|
|
}
|
2008-08-06 22:23:48 +00:00
|
|
|
}
|
2008-03-09 05:11:22 +00:00
|
|
|
|
2013-07-12 11:33:52 +02:00
|
|
|
void
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_add_domain(NMIP4Config *self, const char *domain)
|
2008-03-09 05:11:22 +00:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2013-07-15 17:56:46 -05:00
|
|
|
|
2018-03-24 09:34:35 +01:00
|
|
|
if (_nm_ip_config_check_and_add_domain(priv->domains, domain))
|
|
|
|
|
_notify(self, PROP_DOMAINS);
|
2008-03-09 05:11:22 +00:00
|
|
|
}
|
|
|
|
|
|
2013-08-01 14:04:35 -05:00
|
|
|
void
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_del_domain(NMIP4Config *self, guint i)
|
2013-08-01 14:04:35 -05:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2013-08-01 14:04:35 -05:00
|
|
|
|
|
|
|
|
g_return_if_fail(i < priv->domains->len);
|
|
|
|
|
|
|
|
|
|
g_ptr_array_remove_index(priv->domains, i);
|
2017-07-10 14:03:44 +02:00
|
|
|
_notify(self, PROP_DOMAINS);
|
2013-08-01 14:04:35 -05:00
|
|
|
}
|
|
|
|
|
|
2016-10-14 06:08:41 +02:00
|
|
|
guint
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_get_num_domains(const NMIP4Config *self)
|
2005-04-15 15:43:42 +00:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2005-04-15 15:43:42 +00:00
|
|
|
|
2013-07-12 11:33:52 +02:00
|
|
|
return priv->domains->len;
|
2005-04-15 15:43:42 +00:00
|
|
|
}
|
|
|
|
|
|
2013-07-12 11:33:52 +02:00
|
|
|
const char *
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_get_domain(const NMIP4Config *self, guint i)
|
2005-04-15 15:43:42 +00:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2005-04-15 15:43:42 +00:00
|
|
|
|
2013-07-12 11:33:52 +02:00
|
|
|
return g_ptr_array_index(priv->domains, i);
|
2005-04-15 15:43:42 +00:00
|
|
|
}
|
2005-10-28 03:16:02 +00:00
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2009-05-11 20:02:07 -04:00
|
|
|
|
2013-07-12 11:33:52 +02:00
|
|
|
void
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_reset_searches(NMIP4Config *self)
|
2013-07-12 11:33:52 +02:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2009-05-11 20:02:07 -04:00
|
|
|
|
2013-09-06 11:56:41 +02:00
|
|
|
if (priv->searches->len != 0) {
|
|
|
|
|
g_ptr_array_set_size(priv->searches, 0);
|
2017-07-10 14:03:44 +02:00
|
|
|
_notify(self, PROP_SEARCHES);
|
2013-09-06 11:56:41 +02:00
|
|
|
}
|
2009-05-11 20:02:07 -04:00
|
|
|
}
|
|
|
|
|
|
2013-07-12 11:33:52 +02:00
|
|
|
void
|
2018-03-24 09:34:35 +01:00
|
|
|
nm_ip4_config_add_search(NMIP4Config *self, const char *search)
|
2008-03-09 05:11:22 +00:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2015-12-01 16:55:34 +01:00
|
|
|
|
2018-03-24 09:34:35 +01:00
|
|
|
if (_nm_ip_config_check_and_add_domain(priv->searches, search))
|
|
|
|
|
_notify(self, PROP_SEARCHES);
|
2008-03-09 05:11:22 +00:00
|
|
|
}
|
|
|
|
|
|
2013-08-01 14:04:35 -05:00
|
|
|
void
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_del_search(NMIP4Config *self, guint i)
|
2013-08-01 14:04:35 -05:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2013-08-01 14:04:35 -05:00
|
|
|
|
|
|
|
|
g_return_if_fail(i < priv->searches->len);
|
|
|
|
|
|
|
|
|
|
g_ptr_array_remove_index(priv->searches, i);
|
2017-07-10 14:03:44 +02:00
|
|
|
_notify(self, PROP_SEARCHES);
|
2013-08-01 14:04:35 -05:00
|
|
|
}
|
|
|
|
|
|
2016-10-14 06:08:41 +02:00
|
|
|
guint
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_get_num_searches(const NMIP4Config *self)
|
2008-03-09 05:11:22 +00:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2008-03-09 05:11:22 +00:00
|
|
|
|
2013-07-12 11:33:52 +02:00
|
|
|
return priv->searches->len;
|
2008-03-09 05:11:22 +00:00
|
|
|
}
|
|
|
|
|
|
2013-07-12 11:33:52 +02:00
|
|
|
const char *
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_get_search(const NMIP4Config *self, guint i)
|
2008-03-09 05:11:22 +00:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2008-03-09 05:11:22 +00:00
|
|
|
|
2013-07-12 11:33:52 +02:00
|
|
|
return g_ptr_array_index(priv->searches, i);
|
2008-03-09 05:11:22 +00:00
|
|
|
}
|
|
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2013-07-12 11:33:52 +02:00
|
|
|
|
2015-03-26 09:23:12 +01:00
|
|
|
void
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_reset_dns_options(NMIP4Config *self)
|
2015-03-26 09:23:12 +01:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2015-03-26 09:23:12 +01:00
|
|
|
|
|
|
|
|
if (priv->dns_options->len != 0) {
|
|
|
|
|
g_ptr_array_set_size(priv->dns_options, 0);
|
2017-07-10 14:03:44 +02:00
|
|
|
_notify(self, PROP_DNS_OPTIONS);
|
2015-03-26 09:23:12 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_add_dns_option(NMIP4Config *self, const char *new)
|
2015-03-26 09:23:12 +01:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2015-03-26 09:23:12 +01:00
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
g_return_if_fail(new != NULL);
|
|
|
|
|
g_return_if_fail(new[0] != '\0');
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < priv->dns_options->len; i++)
|
|
|
|
|
if (!g_strcmp0(g_ptr_array_index(priv->dns_options, i), new))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
g_ptr_array_add(priv->dns_options, g_strdup(new));
|
2017-07-10 14:03:44 +02:00
|
|
|
_notify(self, PROP_DNS_OPTIONS);
|
2015-03-26 09:23:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_del_dns_option(NMIP4Config *self, guint i)
|
2015-03-26 09:23:12 +01:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2015-03-26 09:23:12 +01:00
|
|
|
|
|
|
|
|
g_return_if_fail(i < priv->dns_options->len);
|
|
|
|
|
|
|
|
|
|
g_ptr_array_remove_index(priv->dns_options, i);
|
2017-07-10 14:03:44 +02:00
|
|
|
_notify(self, PROP_DNS_OPTIONS);
|
2015-03-26 09:23:12 +01:00
|
|
|
}
|
|
|
|
|
|
2016-10-14 06:08:41 +02:00
|
|
|
guint
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_get_num_dns_options(const NMIP4Config *self)
|
2015-03-26 09:23:12 +01:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2015-03-26 09:23:12 +01:00
|
|
|
|
|
|
|
|
return priv->dns_options->len;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char *
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_get_dns_option(const NMIP4Config *self, guint i)
|
2015-03-26 09:23:12 +01:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2015-03-26 09:23:12 +01:00
|
|
|
|
|
|
|
|
return g_ptr_array_index(priv->dns_options, i);
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2015-03-26 09:23:12 +01:00
|
|
|
|
core: implement setting MDNS setting for systemd
The connection.mdns setting is a per-connection setting,
so one might expect that one activated device can only have
one MDNS setting at a time.
However, with certain VPN plugins (those that don't have their
own IP interface, like libreswan), the VPN configuration is merged
into the configuration of the device. So, in this case, there
might be multiple settings for one device that must be merged.
We already have a mechanism for that. It's NMIP4Config. Let NMIP4Config
track this piece of information. Although, stricitly speaking this
is not tied to IPv4, the alternative would be to introduce a new
object to track such data, which would be a tremendous effort
and more complicated then this.
Luckily, NMDnsManager and NMDnsPlugin are already equipped to
handle multiple NMIPConfig instances per device (IPv4 vs. IPv6,
and Device vs. VPN).
Also make "connection.mdns" configurable via global defaults in
NetworkManager.conf.
2017-12-20 14:49:32 +01:00
|
|
|
NMSettingConnectionMdns
|
|
|
|
|
nm_ip4_config_mdns_get(const NMIP4Config *self)
|
|
|
|
|
{
|
|
|
|
|
return NM_IP4_CONFIG_GET_PRIVATE(self)->mdns;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
nm_ip4_config_mdns_set(NMIP4Config *self, NMSettingConnectionMdns mdns)
|
|
|
|
|
{
|
|
|
|
|
NM_IP4_CONFIG_GET_PRIVATE(self)->mdns = mdns;
|
|
|
|
|
}
|
|
|
|
|
|
2018-08-31 15:14:39 +02:00
|
|
|
NMSettingConnectionLlmnr
|
|
|
|
|
nm_ip4_config_llmnr_get(const NMIP4Config *self)
|
|
|
|
|
{
|
|
|
|
|
return NM_IP4_CONFIG_GET_PRIVATE(self)->llmnr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
nm_ip4_config_llmnr_set(NMIP4Config *self, NMSettingConnectionLlmnr llmnr)
|
|
|
|
|
{
|
|
|
|
|
NM_IP4_CONFIG_GET_PRIVATE(self)->llmnr = llmnr;
|
|
|
|
|
}
|
|
|
|
|
|
core: implement setting MDNS setting for systemd
The connection.mdns setting is a per-connection setting,
so one might expect that one activated device can only have
one MDNS setting at a time.
However, with certain VPN plugins (those that don't have their
own IP interface, like libreswan), the VPN configuration is merged
into the configuration of the device. So, in this case, there
might be multiple settings for one device that must be merged.
We already have a mechanism for that. It's NMIP4Config. Let NMIP4Config
track this piece of information. Although, stricitly speaking this
is not tied to IPv4, the alternative would be to introduce a new
object to track such data, which would be a tremendous effort
and more complicated then this.
Luckily, NMDnsManager and NMDnsPlugin are already equipped to
handle multiple NMIPConfig instances per device (IPv4 vs. IPv6,
and Device vs. VPN).
Also make "connection.mdns" configurable via global defaults in
NetworkManager.conf.
2017-12-20 14:49:32 +01:00
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-04-22 10:35:16 +02:00
|
|
|
NMIPConfigFlags
|
|
|
|
|
nm_ip4_config_get_config_flags(const NMIP4Config *self)
|
|
|
|
|
{
|
|
|
|
|
return NM_IP4_CONFIG_GET_PRIVATE(self)->config_flags;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
nm_ip4_config_set_config_flags(NMIP4Config *self, NMIPConfigFlags flags, NMIPConfigFlags mask)
|
|
|
|
|
{
|
|
|
|
|
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
|
|
|
|
|
|
|
|
|
if (mask == 0) {
|
|
|
|
|
/* for convenience, accept 0 mask to set any flags. */
|
|
|
|
|
mask = flags;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nm_assert(!NM_FLAGS_ANY(flags, ~mask));
|
|
|
|
|
priv->config_flags = (flags & mask) | (priv->config_flags & ~mask);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2016-04-23 15:57:14 +02:00
|
|
|
void
|
all: don't use gchar/gshort/gint/glong but C types
We commonly don't use the glib typedefs for char/short/int/long,
but their C types directly.
$ git grep '\<g\(char\|short\|int\|long\|float\|double\)\>' | wc -l
587
$ git grep '\<\(char\|short\|int\|long\|float\|double\)\>' | wc -l
21114
One could argue that using the glib typedefs is preferable in
public API (of our glib based libnm library) or where it clearly
is related to glib, like during
g_object_set (obj, PROPERTY, (gint) value, NULL);
However, that argument does not seem strong, because in practice we don't
follow that argument today, and seldomly use the glib typedefs.
Also, the style guide for this would be hard to formalize, because
"using them where clearly related to a glib" is a very loose suggestion.
Also note that glib typedefs will always just be typedefs of the
underlying C types. There is no danger of glib changing the meaning
of these typedefs (because that would be a major API break of glib).
A simple style guide is instead: don't use these typedefs.
No manual actions, I only ran the bash script:
FILES=($(git ls-files '*.[hc]'))
sed -i \
-e 's/\<g\(char\|short\|int\|long\|float\|double\)\>\( [^ ]\)/\1\2/g' \
-e 's/\<g\(char\|short\|int\|long\|float\|double\)\> /\1 /g' \
-e 's/\<g\(char\|short\|int\|long\|float\|double\)\>/\1/g' \
"${FILES[@]}"
2018-07-11 07:40:19 +02:00
|
|
|
nm_ip4_config_set_dns_priority(NMIP4Config *self, int priority)
|
2016-04-23 15:57:14 +02:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2016-04-23 15:57:14 +02:00
|
|
|
|
|
|
|
|
if (priority != priv->dns_priority) {
|
|
|
|
|
priv->dns_priority = priority;
|
2017-07-10 14:03:44 +02:00
|
|
|
_notify(self, PROP_DNS_PRIORITY);
|
2016-04-23 15:57:14 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
all: don't use gchar/gshort/gint/glong but C types
We commonly don't use the glib typedefs for char/short/int/long,
but their C types directly.
$ git grep '\<g\(char\|short\|int\|long\|float\|double\)\>' | wc -l
587
$ git grep '\<\(char\|short\|int\|long\|float\|double\)\>' | wc -l
21114
One could argue that using the glib typedefs is preferable in
public API (of our glib based libnm library) or where it clearly
is related to glib, like during
g_object_set (obj, PROPERTY, (gint) value, NULL);
However, that argument does not seem strong, because in practice we don't
follow that argument today, and seldomly use the glib typedefs.
Also, the style guide for this would be hard to formalize, because
"using them where clearly related to a glib" is a very loose suggestion.
Also note that glib typedefs will always just be typedefs of the
underlying C types. There is no danger of glib changing the meaning
of these typedefs (because that would be a major API break of glib).
A simple style guide is instead: don't use these typedefs.
No manual actions, I only ran the bash script:
FILES=($(git ls-files '*.[hc]'))
sed -i \
-e 's/\<g\(char\|short\|int\|long\|float\|double\)\>\( [^ ]\)/\1\2/g' \
-e 's/\<g\(char\|short\|int\|long\|float\|double\)\> /\1 /g' \
-e 's/\<g\(char\|short\|int\|long\|float\|double\)\>/\1/g' \
"${FILES[@]}"
2018-07-11 07:40:19 +02:00
|
|
|
int
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_get_dns_priority(const NMIP4Config *self)
|
2016-04-23 15:57:14 +02:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2016-04-23 15:57:14 +02:00
|
|
|
|
|
|
|
|
return priv->dns_priority;
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2016-04-23 15:57:14 +02:00
|
|
|
|
2013-07-12 11:33:52 +02:00
|
|
|
void
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_reset_nis_servers(NMIP4Config *self)
|
2006-03-29 Robert Love <rml@novell.com>
Patch by Vinay R <rvinay@novell.com> and Robert Love <rml@novell.com>,
to add support for per-route MSS and improve support for per-interface
MTU:
* src/NetworkManagerSystem.c: Modify nm_system_device_set_ip4_route to
optionally take an MSS parameter and set it for the given route.
Remove nm_system_device_set_ip4_route_with_iface. Pass in the
NMIP4Config's stored MSS, if any.
* src/nm-ip4-config.c: Add 'mtu' and 'mss' to NMIP4Config, representing
the interface's MTU and the route's MSS, respectively. Add functions
nm_ip4_config_get_mtu, nm_ip4_config_set_mtu, nm_ip4_config_get_mss,
and nm_ip4_config_set_mss for retrieving and setting the MTU and the
MSS.
* src/nm-ip4-config.h: Add prototypes for nm_ip4_config_get_mtu,
nm_ip4_config_set_mtu, nm_ip4_config_get_mss, and
nm_ip4_config_set_mss.
* src/vpn-manager/nm-vpn-service.c: Modify to receive the MSS from the
VPN daemon.
* src/backends/NetworkManager{Arch,Debian,Gentoo,RedHat,Slackware,SUSE}.c:
Change the retval of nm_system_get_mtu to guint32.
* src/dhcp-manager/nm-dhcp-manager.c: Set the MTU on the new DHCP-given
NMIP4Config to the MTU provided by the system, if any. TODO: If DHCP
servers can specify MTU's, we should set it here if the MTU was not
provided.
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@1660 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2006-03-29 19:26:53 +00:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2006-03-29 Robert Love <rml@novell.com>
Patch by Vinay R <rvinay@novell.com> and Robert Love <rml@novell.com>,
to add support for per-route MSS and improve support for per-interface
MTU:
* src/NetworkManagerSystem.c: Modify nm_system_device_set_ip4_route to
optionally take an MSS parameter and set it for the given route.
Remove nm_system_device_set_ip4_route_with_iface. Pass in the
NMIP4Config's stored MSS, if any.
* src/nm-ip4-config.c: Add 'mtu' and 'mss' to NMIP4Config, representing
the interface's MTU and the route's MSS, respectively. Add functions
nm_ip4_config_get_mtu, nm_ip4_config_set_mtu, nm_ip4_config_get_mss,
and nm_ip4_config_set_mss for retrieving and setting the MTU and the
MSS.
* src/nm-ip4-config.h: Add prototypes for nm_ip4_config_get_mtu,
nm_ip4_config_set_mtu, nm_ip4_config_get_mss, and
nm_ip4_config_set_mss.
* src/vpn-manager/nm-vpn-service.c: Modify to receive the MSS from the
VPN daemon.
* src/backends/NetworkManager{Arch,Debian,Gentoo,RedHat,Slackware,SUSE}.c:
Change the retval of nm_system_get_mtu to guint32.
* src/dhcp-manager/nm-dhcp-manager.c: Set the MTU on the new DHCP-given
NMIP4Config to the MTU provided by the system, if any. TODO: If DHCP
servers can specify MTU's, we should set it here if the MTU was not
provided.
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@1660 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2006-03-29 19:26:53 +00:00
|
|
|
|
2013-07-12 11:33:52 +02:00
|
|
|
g_array_set_size(priv->nis, 0);
|
2006-03-29 Robert Love <rml@novell.com>
Patch by Vinay R <rvinay@novell.com> and Robert Love <rml@novell.com>,
to add support for per-route MSS and improve support for per-interface
MTU:
* src/NetworkManagerSystem.c: Modify nm_system_device_set_ip4_route to
optionally take an MSS parameter and set it for the given route.
Remove nm_system_device_set_ip4_route_with_iface. Pass in the
NMIP4Config's stored MSS, if any.
* src/nm-ip4-config.c: Add 'mtu' and 'mss' to NMIP4Config, representing
the interface's MTU and the route's MSS, respectively. Add functions
nm_ip4_config_get_mtu, nm_ip4_config_set_mtu, nm_ip4_config_get_mss,
and nm_ip4_config_set_mss for retrieving and setting the MTU and the
MSS.
* src/nm-ip4-config.h: Add prototypes for nm_ip4_config_get_mtu,
nm_ip4_config_set_mtu, nm_ip4_config_get_mss, and
nm_ip4_config_set_mss.
* src/vpn-manager/nm-vpn-service.c: Modify to receive the MSS from the
VPN daemon.
* src/backends/NetworkManager{Arch,Debian,Gentoo,RedHat,Slackware,SUSE}.c:
Change the retval of nm_system_get_mtu to guint32.
* src/dhcp-manager/nm-dhcp-manager.c: Set the MTU on the new DHCP-given
NMIP4Config to the MTU provided by the system, if any. TODO: If DHCP
servers can specify MTU's, we should set it here if the MTU was not
provided.
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@1660 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2006-03-29 19:26:53 +00:00
|
|
|
}
|
|
|
|
|
|
2013-07-12 11:33:52 +02:00
|
|
|
void
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_add_nis_server(NMIP4Config *self, guint32 nis)
|
2006-03-29 Robert Love <rml@novell.com>
Patch by Vinay R <rvinay@novell.com> and Robert Love <rml@novell.com>,
to add support for per-route MSS and improve support for per-interface
MTU:
* src/NetworkManagerSystem.c: Modify nm_system_device_set_ip4_route to
optionally take an MSS parameter and set it for the given route.
Remove nm_system_device_set_ip4_route_with_iface. Pass in the
NMIP4Config's stored MSS, if any.
* src/nm-ip4-config.c: Add 'mtu' and 'mss' to NMIP4Config, representing
the interface's MTU and the route's MSS, respectively. Add functions
nm_ip4_config_get_mtu, nm_ip4_config_set_mtu, nm_ip4_config_get_mss,
and nm_ip4_config_set_mss for retrieving and setting the MTU and the
MSS.
* src/nm-ip4-config.h: Add prototypes for nm_ip4_config_get_mtu,
nm_ip4_config_set_mtu, nm_ip4_config_get_mss, and
nm_ip4_config_set_mss.
* src/vpn-manager/nm-vpn-service.c: Modify to receive the MSS from the
VPN daemon.
* src/backends/NetworkManager{Arch,Debian,Gentoo,RedHat,Slackware,SUSE}.c:
Change the retval of nm_system_get_mtu to guint32.
* src/dhcp-manager/nm-dhcp-manager.c: Set the MTU on the new DHCP-given
NMIP4Config to the MTU provided by the system, if any. TODO: If DHCP
servers can specify MTU's, we should set it here if the MTU was not
provided.
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@1660 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2006-03-29 19:26:53 +00:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2013-07-12 11:33:52 +02:00
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < priv->nis->len; i++)
|
|
|
|
|
if (nis == g_array_index(priv->nis, guint32, i))
|
|
|
|
|
return;
|
2006-03-29 Robert Love <rml@novell.com>
Patch by Vinay R <rvinay@novell.com> and Robert Love <rml@novell.com>,
to add support for per-route MSS and improve support for per-interface
MTU:
* src/NetworkManagerSystem.c: Modify nm_system_device_set_ip4_route to
optionally take an MSS parameter and set it for the given route.
Remove nm_system_device_set_ip4_route_with_iface. Pass in the
NMIP4Config's stored MSS, if any.
* src/nm-ip4-config.c: Add 'mtu' and 'mss' to NMIP4Config, representing
the interface's MTU and the route's MSS, respectively. Add functions
nm_ip4_config_get_mtu, nm_ip4_config_set_mtu, nm_ip4_config_get_mss,
and nm_ip4_config_set_mss for retrieving and setting the MTU and the
MSS.
* src/nm-ip4-config.h: Add prototypes for nm_ip4_config_get_mtu,
nm_ip4_config_set_mtu, nm_ip4_config_get_mss, and
nm_ip4_config_set_mss.
* src/vpn-manager/nm-vpn-service.c: Modify to receive the MSS from the
VPN daemon.
* src/backends/NetworkManager{Arch,Debian,Gentoo,RedHat,Slackware,SUSE}.c:
Change the retval of nm_system_get_mtu to guint32.
* src/dhcp-manager/nm-dhcp-manager.c: Set the MTU on the new DHCP-given
NMIP4Config to the MTU provided by the system, if any. TODO: If DHCP
servers can specify MTU's, we should set it here if the MTU was not
provided.
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@1660 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2006-03-29 19:26:53 +00:00
|
|
|
|
2013-07-12 11:33:52 +02:00
|
|
|
g_array_append_val(priv->nis, nis);
|
2006-03-29 Robert Love <rml@novell.com>
Patch by Vinay R <rvinay@novell.com> and Robert Love <rml@novell.com>,
to add support for per-route MSS and improve support for per-interface
MTU:
* src/NetworkManagerSystem.c: Modify nm_system_device_set_ip4_route to
optionally take an MSS parameter and set it for the given route.
Remove nm_system_device_set_ip4_route_with_iface. Pass in the
NMIP4Config's stored MSS, if any.
* src/nm-ip4-config.c: Add 'mtu' and 'mss' to NMIP4Config, representing
the interface's MTU and the route's MSS, respectively. Add functions
nm_ip4_config_get_mtu, nm_ip4_config_set_mtu, nm_ip4_config_get_mss,
and nm_ip4_config_set_mss for retrieving and setting the MTU and the
MSS.
* src/nm-ip4-config.h: Add prototypes for nm_ip4_config_get_mtu,
nm_ip4_config_set_mtu, nm_ip4_config_get_mss, and
nm_ip4_config_set_mss.
* src/vpn-manager/nm-vpn-service.c: Modify to receive the MSS from the
VPN daemon.
* src/backends/NetworkManager{Arch,Debian,Gentoo,RedHat,Slackware,SUSE}.c:
Change the retval of nm_system_get_mtu to guint32.
* src/dhcp-manager/nm-dhcp-manager.c: Set the MTU on the new DHCP-given
NMIP4Config to the MTU provided by the system, if any. TODO: If DHCP
servers can specify MTU's, we should set it here if the MTU was not
provided.
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@1660 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2006-03-29 19:26:53 +00:00
|
|
|
}
|
2005-10-28 03:16:02 +00:00
|
|
|
|
2013-08-01 14:04:35 -05:00
|
|
|
void
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_del_nis_server(NMIP4Config *self, guint i)
|
2013-08-01 14:04:35 -05:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2013-08-01 14:04:35 -05:00
|
|
|
|
|
|
|
|
g_return_if_fail(i < priv->nis->len);
|
|
|
|
|
|
|
|
|
|
g_array_remove_index(priv->nis, i);
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-14 06:08:41 +02:00
|
|
|
guint
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_get_num_nis_servers(const NMIP4Config *self)
|
2008-12-09 20:01:49 +00:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2008-12-09 20:01:49 +00:00
|
|
|
|
2013-07-12 11:33:52 +02:00
|
|
|
return priv->nis->len;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
guint32
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_get_nis_server(const NMIP4Config *self, guint i)
|
2013-07-12 11:33:52 +02:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2013-07-12 11:33:52 +02:00
|
|
|
|
|
|
|
|
return g_array_index(priv->nis, guint32, i);
|
2008-12-09 20:01:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_set_nis_domain(NMIP4Config *self, const char *domain)
|
2008-12-09 20:01:49 +00:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2008-12-09 20:01:49 +00:00
|
|
|
|
2013-07-12 11:33:52 +02:00
|
|
|
g_free(priv->nis_domain);
|
|
|
|
|
priv->nis_domain = g_strdup(domain);
|
2008-12-09 20:01:49 +00:00
|
|
|
}
|
|
|
|
|
|
2013-07-12 11:33:52 +02:00
|
|
|
const char *
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_get_nis_domain(const NMIP4Config *self)
|
2010-07-16 11:28:39 -07:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2010-07-16 11:28:39 -07:00
|
|
|
|
2013-07-12 11:33:52 +02:00
|
|
|
return priv->nis_domain;
|
|
|
|
|
}
|
2010-07-16 11:28:39 -07:00
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2010-07-16 11:28:39 -07:00
|
|
|
|
2013-07-12 11:33:52 +02:00
|
|
|
void
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_reset_wins(NMIP4Config *self)
|
2013-07-12 11:33:52 +02:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2010-07-16 11:28:39 -07:00
|
|
|
|
2013-09-06 11:56:41 +02:00
|
|
|
if (priv->wins->len != 0) {
|
|
|
|
|
g_array_set_size(priv->wins, 0);
|
all: avoid byte ordering issue for IP4Config's Nameservers/WinsServers on D-Bus
Some properties in NetworkManager's D-Bus API are IPv4 addresses
in network byte order (big endian). That is problematic.
It is no problem, when the NetworkManager client runs on the same
host. That is the case with libnm, which does not support to be used
remotely for the time being.
It is a problem for an application that wants to access the D-Bus
interface of NetworkManager remotely. Possibly, such an application
would be implemented in two layers:
- one layer merely remotes D-Bus, without specific knowledge of
NetworkManager's API.
- a higher layer which accesses the remote D-Bus interface of NetworkManager.
Preferably it does so in an agnostic way, regardless of whether it runs
locally or remotely.
When using a D-Bus library, all accesses to 32 bit integers are in
native endianness (regardless of how the integer is actually encoded
on the lower layers). Likewise, D-Bus does not support annotating integer
types in non-native endianness. There is no way to annotate an integer
type "u" to be anything but native order.
That means, when remoting D-Bus at some point the endianness must be
corrected.
But by looking at the D-Bus introspection alone, it is not possible
to know which property need correction and which don't. One would need
to understand the meaning of the properties.
That makes it problematic, because the higher layer of the application,
which knows that the "Nameservers" property is supposed to be in network
order, might not easily know, whether it must correct for endianness.
Deprecate IP4Config properties that are only accessible with a particular
endianness, and add new properties that expose the same data in an
agnostic way.
Note that I added "WinsServerData" to be a plain "as", while
"NameserverData" is of type "aa{sv}". There is no particularly strong
reason for these choices, except that I could imagine that it could be
useful to expose additional information in the future about nameservers
(e.g. are they received via DHCP or manual configuration?). On the other
hand, WINS information likely won't get extended in the future.
Also note, libnm was not modified to use the new D-Bus fields. The
endianness issue is no problem for libnm, so there is little reason to
change it (at this point).
https://bugzilla.redhat.com/show_bug.cgi?id=1153559
https://bugzilla.redhat.com/show_bug.cgi?id=1584584
2018-07-13 20:15:33 +02:00
|
|
|
nm_gobject_notify_together(self, PROP_WINS_SERVER_DATA, PROP_WINS_SERVERS);
|
2013-09-06 11:56:41 +02:00
|
|
|
}
|
2010-07-16 11:28:39 -07:00
|
|
|
}
|
|
|
|
|
|
2013-07-12 11:33:52 +02:00
|
|
|
void
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_add_wins(NMIP4Config *self, guint32 wins)
|
2010-07-16 11:28:39 -07:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2013-07-12 11:33:52 +02:00
|
|
|
int i;
|
|
|
|
|
|
2013-07-15 17:56:46 -05:00
|
|
|
g_return_if_fail(wins != 0);
|
|
|
|
|
|
2013-07-12 11:33:52 +02:00
|
|
|
for (i = 0; i < priv->wins->len; i++)
|
|
|
|
|
if (wins == g_array_index(priv->wins, guint32, i))
|
|
|
|
|
return;
|
2010-07-16 11:28:39 -07:00
|
|
|
|
2013-07-12 11:33:52 +02:00
|
|
|
g_array_append_val(priv->wins, wins);
|
all: avoid byte ordering issue for IP4Config's Nameservers/WinsServers on D-Bus
Some properties in NetworkManager's D-Bus API are IPv4 addresses
in network byte order (big endian). That is problematic.
It is no problem, when the NetworkManager client runs on the same
host. That is the case with libnm, which does not support to be used
remotely for the time being.
It is a problem for an application that wants to access the D-Bus
interface of NetworkManager remotely. Possibly, such an application
would be implemented in two layers:
- one layer merely remotes D-Bus, without specific knowledge of
NetworkManager's API.
- a higher layer which accesses the remote D-Bus interface of NetworkManager.
Preferably it does so in an agnostic way, regardless of whether it runs
locally or remotely.
When using a D-Bus library, all accesses to 32 bit integers are in
native endianness (regardless of how the integer is actually encoded
on the lower layers). Likewise, D-Bus does not support annotating integer
types in non-native endianness. There is no way to annotate an integer
type "u" to be anything but native order.
That means, when remoting D-Bus at some point the endianness must be
corrected.
But by looking at the D-Bus introspection alone, it is not possible
to know which property need correction and which don't. One would need
to understand the meaning of the properties.
That makes it problematic, because the higher layer of the application,
which knows that the "Nameservers" property is supposed to be in network
order, might not easily know, whether it must correct for endianness.
Deprecate IP4Config properties that are only accessible with a particular
endianness, and add new properties that expose the same data in an
agnostic way.
Note that I added "WinsServerData" to be a plain "as", while
"NameserverData" is of type "aa{sv}". There is no particularly strong
reason for these choices, except that I could imagine that it could be
useful to expose additional information in the future about nameservers
(e.g. are they received via DHCP or manual configuration?). On the other
hand, WINS information likely won't get extended in the future.
Also note, libnm was not modified to use the new D-Bus fields. The
endianness issue is no problem for libnm, so there is little reason to
change it (at this point).
https://bugzilla.redhat.com/show_bug.cgi?id=1153559
https://bugzilla.redhat.com/show_bug.cgi?id=1584584
2018-07-13 20:15:33 +02:00
|
|
|
nm_gobject_notify_together(self, PROP_WINS_SERVER_DATA, PROP_WINS_SERVERS);
|
2010-07-16 11:28:39 -07:00
|
|
|
}
|
|
|
|
|
|
2013-08-01 14:04:35 -05:00
|
|
|
void
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_del_wins(NMIP4Config *self, guint i)
|
2013-08-01 14:04:35 -05:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2013-08-01 14:04:35 -05:00
|
|
|
|
|
|
|
|
g_return_if_fail(i < priv->wins->len);
|
|
|
|
|
|
|
|
|
|
g_array_remove_index(priv->wins, i);
|
all: avoid byte ordering issue for IP4Config's Nameservers/WinsServers on D-Bus
Some properties in NetworkManager's D-Bus API are IPv4 addresses
in network byte order (big endian). That is problematic.
It is no problem, when the NetworkManager client runs on the same
host. That is the case with libnm, which does not support to be used
remotely for the time being.
It is a problem for an application that wants to access the D-Bus
interface of NetworkManager remotely. Possibly, such an application
would be implemented in two layers:
- one layer merely remotes D-Bus, without specific knowledge of
NetworkManager's API.
- a higher layer which accesses the remote D-Bus interface of NetworkManager.
Preferably it does so in an agnostic way, regardless of whether it runs
locally or remotely.
When using a D-Bus library, all accesses to 32 bit integers are in
native endianness (regardless of how the integer is actually encoded
on the lower layers). Likewise, D-Bus does not support annotating integer
types in non-native endianness. There is no way to annotate an integer
type "u" to be anything but native order.
That means, when remoting D-Bus at some point the endianness must be
corrected.
But by looking at the D-Bus introspection alone, it is not possible
to know which property need correction and which don't. One would need
to understand the meaning of the properties.
That makes it problematic, because the higher layer of the application,
which knows that the "Nameservers" property is supposed to be in network
order, might not easily know, whether it must correct for endianness.
Deprecate IP4Config properties that are only accessible with a particular
endianness, and add new properties that expose the same data in an
agnostic way.
Note that I added "WinsServerData" to be a plain "as", while
"NameserverData" is of type "aa{sv}". There is no particularly strong
reason for these choices, except that I could imagine that it could be
useful to expose additional information in the future about nameservers
(e.g. are they received via DHCP or manual configuration?). On the other
hand, WINS information likely won't get extended in the future.
Also note, libnm was not modified to use the new D-Bus fields. The
endianness issue is no problem for libnm, so there is little reason to
change it (at this point).
https://bugzilla.redhat.com/show_bug.cgi?id=1153559
https://bugzilla.redhat.com/show_bug.cgi?id=1584584
2018-07-13 20:15:33 +02:00
|
|
|
nm_gobject_notify_together(self, PROP_WINS_SERVER_DATA, PROP_WINS_SERVERS);
|
2013-08-01 14:04:35 -05:00
|
|
|
}
|
|
|
|
|
|
2016-10-14 06:08:41 +02:00
|
|
|
guint
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_get_num_wins(const NMIP4Config *self)
|
2010-07-16 11:28:39 -07:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2010-07-16 11:28:39 -07:00
|
|
|
|
2013-07-12 11:33:52 +02:00
|
|
|
return priv->wins->len;
|
2010-07-16 11:28:39 -07:00
|
|
|
}
|
|
|
|
|
|
2013-07-12 11:33:52 +02:00
|
|
|
guint32
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_get_wins(const NMIP4Config *self, guint i)
|
2010-07-16 11:28:39 -07:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2010-07-16 11:28:39 -07:00
|
|
|
|
2013-07-12 11:33:52 +02:00
|
|
|
return g_array_index(priv->wins, guint32, i);
|
2010-07-16 11:28:39 -07:00
|
|
|
}
|
|
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2013-07-12 11:33:52 +02:00
|
|
|
|
2010-07-16 11:28:39 -07:00
|
|
|
void
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_set_mtu(NMIP4Config *self, guint32 mtu, NMIPConfigSource source)
|
2010-07-16 11:28:39 -07:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2010-07-16 11:28:39 -07:00
|
|
|
|
2017-01-15 12:57:50 +01:00
|
|
|
if (!mtu)
|
|
|
|
|
source = NM_IP_CONFIG_SOURCE_UNKNOWN;
|
|
|
|
|
|
|
|
|
|
priv->mtu = mtu;
|
|
|
|
|
priv->mtu_source = source;
|
2010-07-16 11:28:39 -07:00
|
|
|
}
|
|
|
|
|
|
2013-07-12 11:33:52 +02:00
|
|
|
guint32
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_get_mtu(const NMIP4Config *self)
|
2010-07-16 11:28:39 -07:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2010-07-16 11:28:39 -07:00
|
|
|
|
2013-07-12 11:33:52 +02:00
|
|
|
return priv->mtu;
|
2010-07-16 11:28:39 -07:00
|
|
|
}
|
|
|
|
|
|
2014-10-09 18:51:11 +02:00
|
|
|
NMIPConfigSource
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_get_mtu_source(const NMIP4Config *self)
|
2014-10-09 18:51:11 +02:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2014-10-09 18:51:11 +02:00
|
|
|
|
|
|
|
|
return priv->mtu_source;
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2013-07-12 11:33:52 +02:00
|
|
|
|
2015-04-30 18:11:16 +02:00
|
|
|
void
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_set_metered(NMIP4Config *self, gboolean metered)
|
2015-04-30 18:11:16 +02:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2015-04-30 18:11:16 +02:00
|
|
|
|
2017-01-15 12:33:10 +01:00
|
|
|
priv->metered = metered;
|
2015-04-30 18:11:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_get_metered(const NMIP4Config *self)
|
2015-04-30 18:11:16 +02:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2015-04-30 18:11:16 +02:00
|
|
|
|
|
|
|
|
return priv->metered;
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2015-04-30 18:11:16 +02:00
|
|
|
|
2020-09-29 12:06:11 +02:00
|
|
|
void
|
|
|
|
|
nm_ip4_config_set_never_default(NMIP4Config *self, gboolean never_default)
|
|
|
|
|
{
|
|
|
|
|
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
|
|
|
|
|
|
|
|
|
priv->never_default = never_default;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
|
nm_ip4_config_get_never_default(const NMIP4Config *self)
|
|
|
|
|
{
|
|
|
|
|
const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
|
|
|
|
|
|
|
|
|
return priv->never_default;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2017-08-31 13:39:04 +02:00
|
|
|
const NMPObject *
|
|
|
|
|
nm_ip4_config_nmpobj_lookup(const NMIP4Config *self, const NMPObject *needle)
|
|
|
|
|
{
|
|
|
|
|
const NMIP4ConfigPrivate * priv;
|
|
|
|
|
const NMDedupMultiIdxType *idx_type;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail(NM_IS_IP4_CONFIG(self), NULL);
|
|
|
|
|
|
|
|
|
|
priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
|
|
|
|
switch (NMP_OBJECT_GET_TYPE(needle)) {
|
|
|
|
|
case NMP_OBJECT_TYPE_IP4_ADDRESS:
|
|
|
|
|
idx_type = &priv->idx_ip4_addresses;
|
|
|
|
|
break;
|
|
|
|
|
case NMP_OBJECT_TYPE_IP4_ROUTE:
|
|
|
|
|
idx_type = &priv->idx_ip4_routes;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
g_return_val_if_reached(NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nm_dedup_multi_entry_get_obj(
|
|
|
|
|
nm_dedup_multi_index_lookup_obj(priv->multi_idx, idx_type, needle));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
|
nm_ip4_config_nmpobj_remove(NMIP4Config *self, const NMPObject *needle)
|
|
|
|
|
{
|
|
|
|
|
NMIP4ConfigPrivate * priv;
|
|
|
|
|
NMDedupMultiIdxType *idx_type;
|
|
|
|
|
nm_auto_nmpobj const NMPObject *obj_old = NULL;
|
|
|
|
|
guint n;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-08-31 13:39:04 +02:00
|
|
|
g_return_val_if_fail(NM_IS_IP4_CONFIG(self), FALSE);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-08-31 13:39:04 +02:00
|
|
|
priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
|
|
|
|
switch (NMP_OBJECT_GET_TYPE(needle)) {
|
|
|
|
|
case NMP_OBJECT_TYPE_IP4_ADDRESS:
|
|
|
|
|
idx_type = &priv->idx_ip4_addresses;
|
|
|
|
|
break;
|
|
|
|
|
case NMP_OBJECT_TYPE_IP4_ROUTE:
|
|
|
|
|
idx_type = &priv->idx_ip4_routes;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
g_return_val_if_reached(FALSE);
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-08-31 13:39:04 +02:00
|
|
|
n = nm_dedup_multi_index_remove_obj(priv->multi_idx,
|
|
|
|
|
idx_type,
|
|
|
|
|
needle,
|
|
|
|
|
(gconstpointer *) &obj_old);
|
|
|
|
|
if (n != 1) {
|
|
|
|
|
nm_assert(n == 0);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-08-31 13:39:04 +02:00
|
|
|
nm_assert(NMP_OBJECT_GET_TYPE(obj_old) == NMP_OBJECT_GET_TYPE(needle));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-08-31 13:39:04 +02:00
|
|
|
switch (NMP_OBJECT_GET_TYPE(obj_old)) {
|
|
|
|
|
case NMP_OBJECT_TYPE_IP4_ADDRESS:
|
|
|
|
|
_notify_addresses(self);
|
|
|
|
|
break;
|
|
|
|
|
case NMP_OBJECT_TYPE_IP4_ROUTE:
|
|
|
|
|
if (priv->best_default_route == obj_old) {
|
2020-07-21 17:49:23 +02:00
|
|
|
if (nmp_object_ref_set(&priv->best_default_route,
|
|
|
|
|
_nm_ip4_config_best_default_route_find(self)))
|
2017-10-04 15:21:21 +02:00
|
|
|
_notify(self, PROP_GATEWAY);
|
2017-08-31 13:39:04 +02:00
|
|
|
}
|
|
|
|
|
_notify_routes(self);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
nm_assert_not_reached();
|
|
|
|
|
}
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2019-02-06 09:04:23 +01:00
|
|
|
static void
|
2012-05-29 22:24:51 -05:00
|
|
|
hash_u32(GChecksum *sum, guint32 n)
|
|
|
|
|
{
|
|
|
|
|
g_checksum_update(sum, (const guint8 *) &n, sizeof(n));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_hash(const NMIP4Config *self, GChecksum *sum, gboolean dns_only)
|
2012-05-29 22:24:51 -05:00
|
|
|
{
|
2016-10-14 06:08:41 +02:00
|
|
|
guint i;
|
2012-05-29 22:24:51 -05:00
|
|
|
const char * s;
|
2017-06-12 18:40:14 +02:00
|
|
|
NMDedupMultiIter ipconf_iter;
|
2017-07-07 23:34:41 +02:00
|
|
|
const NMPlatformIP4Address *address;
|
2017-06-12 18:40:14 +02:00
|
|
|
const NMPlatformIP4Route * route;
|
2018-08-31 17:02:21 +02:00
|
|
|
int val;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-07-10 14:03:44 +02:00
|
|
|
g_return_if_fail(self);
|
2013-07-04 15:40:01 +02:00
|
|
|
g_return_if_fail(sum);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-07-04 15:40:01 +02:00
|
|
|
if (!dns_only) {
|
2017-07-07 23:34:41 +02:00
|
|
|
nm_ip_config_iter_ip4_address_for_each (&ipconf_iter, self, &address) {
|
2013-06-29 13:33:36 +02:00
|
|
|
hash_u32(sum, address->address);
|
|
|
|
|
hash_u32(sum, address->plen);
|
2017-09-05 15:25:34 +02:00
|
|
|
hash_u32(sum, address->peer_address & _nm_utils_ip4_prefix_to_netmask(address->plen));
|
2012-05-29 22:24:51 -05:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-07-07 23:34:41 +02:00
|
|
|
nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, self, &route) {
|
2013-07-31 23:07:32 +02:00
|
|
|
hash_u32(sum, route->network);
|
|
|
|
|
hash_u32(sum, route->plen);
|
|
|
|
|
hash_u32(sum, route->gateway);
|
|
|
|
|
hash_u32(sum, route->metric);
|
2012-05-29 22:24:51 -05:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-07-10 14:03:44 +02:00
|
|
|
for (i = 0; i < nm_ip4_config_get_num_nis_servers(self); i++)
|
|
|
|
|
hash_u32(sum, nm_ip4_config_get_nis_server(self, i));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-07-10 14:03:44 +02:00
|
|
|
s = nm_ip4_config_get_nis_domain(self);
|
2012-05-29 22:24:51 -05:00
|
|
|
if (s)
|
|
|
|
|
g_checksum_update(sum, (const guint8 *) s, strlen(s));
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-07-10 14:03:44 +02:00
|
|
|
for (i = 0; i < nm_ip4_config_get_num_nameservers(self); i++)
|
|
|
|
|
hash_u32(sum, nm_ip4_config_get_nameserver(self, i));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-07-10 14:03:44 +02:00
|
|
|
for (i = 0; i < nm_ip4_config_get_num_wins(self); i++)
|
|
|
|
|
hash_u32(sum, nm_ip4_config_get_wins(self, i));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-07-10 14:03:44 +02:00
|
|
|
for (i = 0; i < nm_ip4_config_get_num_domains(self); i++) {
|
|
|
|
|
s = nm_ip4_config_get_domain(self, i);
|
2012-05-29 22:24:51 -05:00
|
|
|
g_checksum_update(sum, (const guint8 *) s, strlen(s));
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-07-10 14:03:44 +02:00
|
|
|
for (i = 0; i < nm_ip4_config_get_num_searches(self); i++) {
|
|
|
|
|
s = nm_ip4_config_get_search(self, i);
|
2012-05-29 22:24:51 -05:00
|
|
|
g_checksum_update(sum, (const guint8 *) s, strlen(s));
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-07-10 14:03:44 +02:00
|
|
|
for (i = 0; i < nm_ip4_config_get_num_dns_options(self); i++) {
|
|
|
|
|
s = nm_ip4_config_get_dns_option(self, i);
|
2015-03-26 09:23:12 +01:00
|
|
|
g_checksum_update(sum, (const guint8 *) s, strlen(s));
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2018-08-31 17:02:21 +02:00
|
|
|
val = nm_ip4_config_mdns_get(self);
|
|
|
|
|
if (val != NM_SETTING_CONNECTION_MDNS_DEFAULT)
|
|
|
|
|
g_checksum_update(sum, (const guint8 *) &val, sizeof(val));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2018-08-31 17:02:21 +02:00
|
|
|
val = nm_ip4_config_llmnr_get(self);
|
|
|
|
|
if (val != NM_SETTING_CONNECTION_LLMNR_DEFAULT)
|
|
|
|
|
g_checksum_update(sum, (const guint8 *) &val, sizeof(val));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2018-08-31 17:02:21 +02:00
|
|
|
/* FIXME(ip-config-checksum): the DNS priority should be considered relevant
|
|
|
|
|
* and added into the checksum as well, but this can't be done right now
|
|
|
|
|
* because in the DNS manager we rely on the fact that an empty
|
|
|
|
|
* configuration (i.e. just created) has a zero checksum. This is needed to
|
|
|
|
|
* avoid rewriting resolv.conf when there is no change.
|
|
|
|
|
*
|
|
|
|
|
* The DNS priority initial value depends on the connection type (VPN or
|
|
|
|
|
* not), so it's a bit difficult to add it to checksum maintaining the
|
|
|
|
|
* assumption of checksum(empty)=0
|
|
|
|
|
*/
|
2012-05-29 22:24:51 -05:00
|
|
|
}
|
|
|
|
|
|
2014-01-06 14:14:14 -06:00
|
|
|
/**
|
|
|
|
|
* nm_ip4_config_equal:
|
|
|
|
|
* @a: first config to compare
|
|
|
|
|
* @b: second config to compare
|
|
|
|
|
*
|
|
|
|
|
* Compares two #NMIP4Configs for basic equality. This means that all
|
|
|
|
|
* attributes must exist in the same order in both configs (addresses, routes,
|
|
|
|
|
* domains, DNS servers, etc) but some attributes (address lifetimes, and address
|
|
|
|
|
* and route sources) are ignored.
|
|
|
|
|
*
|
|
|
|
|
* Returns: %TRUE if the configurations are basically equal to each other,
|
|
|
|
|
* %FALSE if not
|
|
|
|
|
*/
|
2013-07-04 15:40:01 +02:00
|
|
|
gboolean
|
2013-09-25 13:08:53 +02:00
|
|
|
nm_ip4_config_equal(const NMIP4Config *a, const NMIP4Config *b)
|
2013-07-04 15:40:01 +02:00
|
|
|
{
|
2018-11-01 12:52:38 +01:00
|
|
|
nm_auto_free_checksum GChecksum *a_checksum = g_checksum_new(G_CHECKSUM_SHA1);
|
|
|
|
|
nm_auto_free_checksum GChecksum *b_checksum = g_checksum_new(G_CHECKSUM_SHA1);
|
|
|
|
|
guint8 a_data[NM_UTILS_CHECKSUM_LENGTH_SHA1];
|
|
|
|
|
guint8 b_data[NM_UTILS_CHECKSUM_LENGTH_SHA1];
|
2013-07-04 15:40:01 +02:00
|
|
|
|
|
|
|
|
if (a)
|
|
|
|
|
nm_ip4_config_hash(a, a_checksum, FALSE);
|
|
|
|
|
if (b)
|
|
|
|
|
nm_ip4_config_hash(b, b_checksum, FALSE);
|
|
|
|
|
|
2018-11-01 12:52:38 +01:00
|
|
|
nm_utils_checksum_get_digest(a_checksum, a_data);
|
|
|
|
|
nm_utils_checksum_get_digest(b_checksum, b_data);
|
|
|
|
|
return !memcmp(a_data, b_data, sizeof(a_data));
|
2013-07-04 15:40:01 +02:00
|
|
|
}
|
|
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2013-07-12 11:33:52 +02:00
|
|
|
|
2007-02-16 11:23:49 +00:00
|
|
|
static void
|
|
|
|
|
get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
|
|
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
NMIP4Config * self = NM_IP4_CONFIG(object);
|
|
|
|
|
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2018-11-26 16:49:51 +01:00
|
|
|
char addr_str[NM_UTILS_INET_ADDRSTRLEN];
|
2020-07-30 11:02:56 +02:00
|
|
|
GVariantBuilder builder_data;
|
|
|
|
|
guint i;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2007-02-16 11:23:49 +00:00
|
|
|
switch (prop_id) {
|
2015-02-20 16:31:10 -06:00
|
|
|
case PROP_IFINDEX:
|
|
|
|
|
g_value_set_int(value, priv->ifindex);
|
|
|
|
|
break;
|
libnm-core, libnm, core: add AddressData and RouteData properties
Add AddressData and RouteData properties to NMSettingIPConfig and
NMIP[46]Config. These are like the existing "addresses" and "routes"
properties, but using strings and containing additional attributes,
like NMIPAddress and NMIPRoute.
This only affects the D-Bus representations; there are no API changes
to NMSettingIP{,4,6}Config or NMIP{4,6}Config as a result of this; the
additional information is just added to the existing 'addresses' and
'routes' properties.
NMSettingIP4Config and NMSettingIP6Config now always generate both
old-style data ('addresses', 'address-labels', 'routes') and new-style
data ('address-data', 'gateway', 'route-data') when serializing to
D-Bus, for backward compatibility. When deserializing, they will fill
in the 'addresses' and 'routes' properties from the new-style data if
it is present (ignoring the old-style data), or from the old-style
data if the new-style isn't present.
The daemon-side NMIP4Config and NMIP6Config always emit changes for
both 'Addresses'/'Routes' and 'AddressData'/'RouteData'. The
libnm-side classes initially listen for changes on both properties,
but start ignoring the 'Addresses' and 'Routes' properties once they
know the daemon is also providing 'AddressData' and 'RouteData'.
2014-10-21 08:33:18 -04:00
|
|
|
case PROP_ADDRESS_DATA:
|
2016-11-18 11:52:38 +01:00
|
|
|
case PROP_ADDRESSES:
|
2017-07-11 13:20:23 +02:00
|
|
|
nm_assert(!!priv->address_data_variant == !!priv->addresses_variant);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-07-30 11:02:56 +02:00
|
|
|
if (!priv->address_data_variant) {
|
2020-07-30 13:24:48 +02:00
|
|
|
nm_utils_ip_addresses_to_dbus(AF_INET,
|
|
|
|
|
nm_ip4_config_lookup_addresses(self),
|
|
|
|
|
priv->best_default_route,
|
|
|
|
|
NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN,
|
|
|
|
|
&priv->address_data_variant,
|
|
|
|
|
&priv->addresses_variant);
|
2020-07-30 11:02:56 +02:00
|
|
|
g_variant_ref_sink(priv->address_data_variant);
|
|
|
|
|
g_variant_ref_sink(priv->addresses_variant);
|
2017-07-07 23:34:41 +02:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-07-07 23:34:41 +02:00
|
|
|
g_value_set_variant(value,
|
2020-07-30 11:02:56 +02:00
|
|
|
prop_id == PROP_ADDRESS_DATA ? priv->address_data_variant
|
|
|
|
|
: priv->addresses_variant);
|
2007-02-16 11:23:49 +00:00
|
|
|
break;
|
libnm-core, libnm, core: add AddressData and RouteData properties
Add AddressData and RouteData properties to NMSettingIPConfig and
NMIP[46]Config. These are like the existing "addresses" and "routes"
properties, but using strings and containing additional attributes,
like NMIPAddress and NMIPRoute.
This only affects the D-Bus representations; there are no API changes
to NMSettingIP{,4,6}Config or NMIP{4,6}Config as a result of this; the
additional information is just added to the existing 'addresses' and
'routes' properties.
NMSettingIP4Config and NMSettingIP6Config now always generate both
old-style data ('addresses', 'address-labels', 'routes') and new-style
data ('address-data', 'gateway', 'route-data') when serializing to
D-Bus, for backward compatibility. When deserializing, they will fill
in the 'addresses' and 'routes' properties from the new-style data if
it is present (ignoring the old-style data), or from the old-style
data if the new-style isn't present.
The daemon-side NMIP4Config and NMIP6Config always emit changes for
both 'Addresses'/'Routes' and 'AddressData'/'RouteData'. The
libnm-side classes initially listen for changes on both properties,
but start ignoring the 'Addresses' and 'Routes' properties once they
know the daemon is also providing 'AddressData' and 'RouteData'.
2014-10-21 08:33:18 -04:00
|
|
|
case PROP_ROUTE_DATA:
|
2017-07-11 13:20:23 +02:00
|
|
|
case PROP_ROUTES:
|
|
|
|
|
nm_assert(!!priv->route_data_variant == !!priv->routes_variant);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-07-30 11:02:56 +02:00
|
|
|
if (!priv->route_data_variant) {
|
2020-07-30 13:24:48 +02:00
|
|
|
nm_utils_ip_routes_to_dbus(AF_INET,
|
|
|
|
|
nm_ip4_config_lookup_routes(self),
|
|
|
|
|
&priv->route_data_variant,
|
|
|
|
|
&priv->routes_variant);
|
2020-07-30 11:02:56 +02:00
|
|
|
g_variant_ref_sink(priv->route_data_variant);
|
|
|
|
|
g_variant_ref_sink(priv->routes_variant);
|
2013-07-31 23:07:32 +02:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-07-11 13:20:23 +02:00
|
|
|
g_value_set_variant(value,
|
2020-07-30 11:02:56 +02:00
|
|
|
prop_id == PROP_ROUTE_DATA ? priv->route_data_variant
|
|
|
|
|
: priv->routes_variant);
|
2013-07-12 11:33:52 +02:00
|
|
|
break;
|
libnm-core, libnm, core: add AddressData and RouteData properties
Add AddressData and RouteData properties to NMSettingIPConfig and
NMIP[46]Config. These are like the existing "addresses" and "routes"
properties, but using strings and containing additional attributes,
like NMIPAddress and NMIPRoute.
This only affects the D-Bus representations; there are no API changes
to NMSettingIP{,4,6}Config or NMIP{4,6}Config as a result of this; the
additional information is just added to the existing 'addresses' and
'routes' properties.
NMSettingIP4Config and NMSettingIP6Config now always generate both
old-style data ('addresses', 'address-labels', 'routes') and new-style
data ('address-data', 'gateway', 'route-data') when serializing to
D-Bus, for backward compatibility. When deserializing, they will fill
in the 'addresses' and 'routes' properties from the new-style data if
it is present (ignoring the old-style data), or from the old-style
data if the new-style isn't present.
The daemon-side NMIP4Config and NMIP6Config always emit changes for
both 'Addresses'/'Routes' and 'AddressData'/'RouteData'. The
libnm-side classes initially listen for changes on both properties,
but start ignoring the 'Addresses' and 'Routes' properties once they
know the daemon is also providing 'AddressData' and 'RouteData'.
2014-10-21 08:33:18 -04:00
|
|
|
case PROP_GATEWAY:
|
2017-10-04 15:21:21 +02:00
|
|
|
if (priv->best_default_route) {
|
2018-11-26 16:49:51 +01:00
|
|
|
g_value_take_string(value,
|
|
|
|
|
nm_utils_inet4_ntop_dup(
|
|
|
|
|
NMP_OBJECT_CAST_IP4_ROUTE(priv->best_default_route)->gateway));
|
2017-10-04 15:21:21 +02:00
|
|
|
} else
|
libnm-core, libnm, core: add AddressData and RouteData properties
Add AddressData and RouteData properties to NMSettingIPConfig and
NMIP[46]Config. These are like the existing "addresses" and "routes"
properties, but using strings and containing additional attributes,
like NMIPAddress and NMIPRoute.
This only affects the D-Bus representations; there are no API changes
to NMSettingIP{,4,6}Config or NMIP{4,6}Config as a result of this; the
additional information is just added to the existing 'addresses' and
'routes' properties.
NMSettingIP4Config and NMSettingIP6Config now always generate both
old-style data ('addresses', 'address-labels', 'routes') and new-style
data ('address-data', 'gateway', 'route-data') when serializing to
D-Bus, for backward compatibility. When deserializing, they will fill
in the 'addresses' and 'routes' properties from the new-style data if
it is present (ignoring the old-style data), or from the old-style
data if the new-style isn't present.
The daemon-side NMIP4Config and NMIP6Config always emit changes for
both 'Addresses'/'Routes' and 'AddressData'/'RouteData'. The
libnm-side classes initially listen for changes on both properties,
but start ignoring the 'Addresses' and 'Routes' properties once they
know the daemon is also providing 'AddressData' and 'RouteData'.
2014-10-21 08:33:18 -04:00
|
|
|
g_value_set_string(value, NULL);
|
|
|
|
|
break;
|
all: avoid byte ordering issue for IP4Config's Nameservers/WinsServers on D-Bus
Some properties in NetworkManager's D-Bus API are IPv4 addresses
in network byte order (big endian). That is problematic.
It is no problem, when the NetworkManager client runs on the same
host. That is the case with libnm, which does not support to be used
remotely for the time being.
It is a problem for an application that wants to access the D-Bus
interface of NetworkManager remotely. Possibly, such an application
would be implemented in two layers:
- one layer merely remotes D-Bus, without specific knowledge of
NetworkManager's API.
- a higher layer which accesses the remote D-Bus interface of NetworkManager.
Preferably it does so in an agnostic way, regardless of whether it runs
locally or remotely.
When using a D-Bus library, all accesses to 32 bit integers are in
native endianness (regardless of how the integer is actually encoded
on the lower layers). Likewise, D-Bus does not support annotating integer
types in non-native endianness. There is no way to annotate an integer
type "u" to be anything but native order.
That means, when remoting D-Bus at some point the endianness must be
corrected.
But by looking at the D-Bus introspection alone, it is not possible
to know which property need correction and which don't. One would need
to understand the meaning of the properties.
That makes it problematic, because the higher layer of the application,
which knows that the "Nameservers" property is supposed to be in network
order, might not easily know, whether it must correct for endianness.
Deprecate IP4Config properties that are only accessible with a particular
endianness, and add new properties that expose the same data in an
agnostic way.
Note that I added "WinsServerData" to be a plain "as", while
"NameserverData" is of type "aa{sv}". There is no particularly strong
reason for these choices, except that I could imagine that it could be
useful to expose additional information in the future about nameservers
(e.g. are they received via DHCP or manual configuration?). On the other
hand, WINS information likely won't get extended in the future.
Also note, libnm was not modified to use the new D-Bus fields. The
endianness issue is no problem for libnm, so there is little reason to
change it (at this point).
https://bugzilla.redhat.com/show_bug.cgi?id=1153559
https://bugzilla.redhat.com/show_bug.cgi?id=1584584
2018-07-13 20:15:33 +02:00
|
|
|
case PROP_NAMESERVER_DATA:
|
|
|
|
|
g_variant_builder_init(&builder_data, G_VARIANT_TYPE("aa{sv}"));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
all: avoid byte ordering issue for IP4Config's Nameservers/WinsServers on D-Bus
Some properties in NetworkManager's D-Bus API are IPv4 addresses
in network byte order (big endian). That is problematic.
It is no problem, when the NetworkManager client runs on the same
host. That is the case with libnm, which does not support to be used
remotely for the time being.
It is a problem for an application that wants to access the D-Bus
interface of NetworkManager remotely. Possibly, such an application
would be implemented in two layers:
- one layer merely remotes D-Bus, without specific knowledge of
NetworkManager's API.
- a higher layer which accesses the remote D-Bus interface of NetworkManager.
Preferably it does so in an agnostic way, regardless of whether it runs
locally or remotely.
When using a D-Bus library, all accesses to 32 bit integers are in
native endianness (regardless of how the integer is actually encoded
on the lower layers). Likewise, D-Bus does not support annotating integer
types in non-native endianness. There is no way to annotate an integer
type "u" to be anything but native order.
That means, when remoting D-Bus at some point the endianness must be
corrected.
But by looking at the D-Bus introspection alone, it is not possible
to know which property need correction and which don't. One would need
to understand the meaning of the properties.
That makes it problematic, because the higher layer of the application,
which knows that the "Nameservers" property is supposed to be in network
order, might not easily know, whether it must correct for endianness.
Deprecate IP4Config properties that are only accessible with a particular
endianness, and add new properties that expose the same data in an
agnostic way.
Note that I added "WinsServerData" to be a plain "as", while
"NameserverData" is of type "aa{sv}". There is no particularly strong
reason for these choices, except that I could imagine that it could be
useful to expose additional information in the future about nameservers
(e.g. are they received via DHCP or manual configuration?). On the other
hand, WINS information likely won't get extended in the future.
Also note, libnm was not modified to use the new D-Bus fields. The
endianness issue is no problem for libnm, so there is little reason to
change it (at this point).
https://bugzilla.redhat.com/show_bug.cgi?id=1153559
https://bugzilla.redhat.com/show_bug.cgi?id=1584584
2018-07-13 20:15:33 +02:00
|
|
|
for (i = 0; i < priv->nameservers->len; i++) {
|
|
|
|
|
GVariantBuilder nested_builder;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-01-09 11:29:27 +01:00
|
|
|
_nm_utils_inet4_ntop(g_array_index(priv->nameservers, in_addr_t, i), addr_str);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
all: avoid byte ordering issue for IP4Config's Nameservers/WinsServers on D-Bus
Some properties in NetworkManager's D-Bus API are IPv4 addresses
in network byte order (big endian). That is problematic.
It is no problem, when the NetworkManager client runs on the same
host. That is the case with libnm, which does not support to be used
remotely for the time being.
It is a problem for an application that wants to access the D-Bus
interface of NetworkManager remotely. Possibly, such an application
would be implemented in two layers:
- one layer merely remotes D-Bus, without specific knowledge of
NetworkManager's API.
- a higher layer which accesses the remote D-Bus interface of NetworkManager.
Preferably it does so in an agnostic way, regardless of whether it runs
locally or remotely.
When using a D-Bus library, all accesses to 32 bit integers are in
native endianness (regardless of how the integer is actually encoded
on the lower layers). Likewise, D-Bus does not support annotating integer
types in non-native endianness. There is no way to annotate an integer
type "u" to be anything but native order.
That means, when remoting D-Bus at some point the endianness must be
corrected.
But by looking at the D-Bus introspection alone, it is not possible
to know which property need correction and which don't. One would need
to understand the meaning of the properties.
That makes it problematic, because the higher layer of the application,
which knows that the "Nameservers" property is supposed to be in network
order, might not easily know, whether it must correct for endianness.
Deprecate IP4Config properties that are only accessible with a particular
endianness, and add new properties that expose the same data in an
agnostic way.
Note that I added "WinsServerData" to be a plain "as", while
"NameserverData" is of type "aa{sv}". There is no particularly strong
reason for these choices, except that I could imagine that it could be
useful to expose additional information in the future about nameservers
(e.g. are they received via DHCP or manual configuration?). On the other
hand, WINS information likely won't get extended in the future.
Also note, libnm was not modified to use the new D-Bus fields. The
endianness issue is no problem for libnm, so there is little reason to
change it (at this point).
https://bugzilla.redhat.com/show_bug.cgi?id=1153559
https://bugzilla.redhat.com/show_bug.cgi?id=1584584
2018-07-13 20:15:33 +02:00
|
|
|
g_variant_builder_init(&nested_builder, G_VARIANT_TYPE("a{sv}"));
|
|
|
|
|
g_variant_builder_add(&nested_builder,
|
|
|
|
|
"{sv}",
|
|
|
|
|
"address",
|
|
|
|
|
g_variant_new_string(addr_str));
|
|
|
|
|
g_variant_builder_add(&builder_data, "a{sv}", &nested_builder);
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
all: avoid byte ordering issue for IP4Config's Nameservers/WinsServers on D-Bus
Some properties in NetworkManager's D-Bus API are IPv4 addresses
in network byte order (big endian). That is problematic.
It is no problem, when the NetworkManager client runs on the same
host. That is the case with libnm, which does not support to be used
remotely for the time being.
It is a problem for an application that wants to access the D-Bus
interface of NetworkManager remotely. Possibly, such an application
would be implemented in two layers:
- one layer merely remotes D-Bus, without specific knowledge of
NetworkManager's API.
- a higher layer which accesses the remote D-Bus interface of NetworkManager.
Preferably it does so in an agnostic way, regardless of whether it runs
locally or remotely.
When using a D-Bus library, all accesses to 32 bit integers are in
native endianness (regardless of how the integer is actually encoded
on the lower layers). Likewise, D-Bus does not support annotating integer
types in non-native endianness. There is no way to annotate an integer
type "u" to be anything but native order.
That means, when remoting D-Bus at some point the endianness must be
corrected.
But by looking at the D-Bus introspection alone, it is not possible
to know which property need correction and which don't. One would need
to understand the meaning of the properties.
That makes it problematic, because the higher layer of the application,
which knows that the "Nameservers" property is supposed to be in network
order, might not easily know, whether it must correct for endianness.
Deprecate IP4Config properties that are only accessible with a particular
endianness, and add new properties that expose the same data in an
agnostic way.
Note that I added "WinsServerData" to be a plain "as", while
"NameserverData" is of type "aa{sv}". There is no particularly strong
reason for these choices, except that I could imagine that it could be
useful to expose additional information in the future about nameservers
(e.g. are they received via DHCP or manual configuration?). On the other
hand, WINS information likely won't get extended in the future.
Also note, libnm was not modified to use the new D-Bus fields. The
endianness issue is no problem for libnm, so there is little reason to
change it (at this point).
https://bugzilla.redhat.com/show_bug.cgi?id=1153559
https://bugzilla.redhat.com/show_bug.cgi?id=1584584
2018-07-13 20:15:33 +02:00
|
|
|
g_value_take_variant(value, g_variant_builder_end(&builder_data));
|
|
|
|
|
break;
|
2007-02-16 11:23:49 +00:00
|
|
|
case PROP_NAMESERVERS:
|
2015-04-15 14:53:30 -04:00
|
|
|
g_value_take_variant(value,
|
|
|
|
|
g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
|
|
|
|
|
priv->nameservers->data,
|
|
|
|
|
priv->nameservers->len,
|
|
|
|
|
sizeof(guint32)));
|
2007-02-16 11:23:49 +00:00
|
|
|
break;
|
|
|
|
|
case PROP_DOMAINS:
|
2015-04-15 14:53:30 -04:00
|
|
|
nm_utils_g_value_set_strv(value, priv->domains);
|
2007-02-16 11:23:49 +00:00
|
|
|
break;
|
2013-09-06 11:56:41 +02:00
|
|
|
case PROP_SEARCHES:
|
2015-04-15 14:53:30 -04:00
|
|
|
nm_utils_g_value_set_strv(value, priv->searches);
|
2013-09-06 11:56:41 +02:00
|
|
|
break;
|
2015-03-26 09:23:12 +01:00
|
|
|
case PROP_DNS_OPTIONS:
|
2015-04-15 14:53:30 -04:00
|
|
|
nm_utils_g_value_set_strv(value, priv->dns_options);
|
2015-03-26 09:23:12 +01:00
|
|
|
break;
|
2016-04-23 15:57:14 +02:00
|
|
|
case PROP_DNS_PRIORITY:
|
|
|
|
|
g_value_set_int(value, priv->dns_priority);
|
|
|
|
|
break;
|
all: avoid byte ordering issue for IP4Config's Nameservers/WinsServers on D-Bus
Some properties in NetworkManager's D-Bus API are IPv4 addresses
in network byte order (big endian). That is problematic.
It is no problem, when the NetworkManager client runs on the same
host. That is the case with libnm, which does not support to be used
remotely for the time being.
It is a problem for an application that wants to access the D-Bus
interface of NetworkManager remotely. Possibly, such an application
would be implemented in two layers:
- one layer merely remotes D-Bus, without specific knowledge of
NetworkManager's API.
- a higher layer which accesses the remote D-Bus interface of NetworkManager.
Preferably it does so in an agnostic way, regardless of whether it runs
locally or remotely.
When using a D-Bus library, all accesses to 32 bit integers are in
native endianness (regardless of how the integer is actually encoded
on the lower layers). Likewise, D-Bus does not support annotating integer
types in non-native endianness. There is no way to annotate an integer
type "u" to be anything but native order.
That means, when remoting D-Bus at some point the endianness must be
corrected.
But by looking at the D-Bus introspection alone, it is not possible
to know which property need correction and which don't. One would need
to understand the meaning of the properties.
That makes it problematic, because the higher layer of the application,
which knows that the "Nameservers" property is supposed to be in network
order, might not easily know, whether it must correct for endianness.
Deprecate IP4Config properties that are only accessible with a particular
endianness, and add new properties that expose the same data in an
agnostic way.
Note that I added "WinsServerData" to be a plain "as", while
"NameserverData" is of type "aa{sv}". There is no particularly strong
reason for these choices, except that I could imagine that it could be
useful to expose additional information in the future about nameservers
(e.g. are they received via DHCP or manual configuration?). On the other
hand, WINS information likely won't get extended in the future.
Also note, libnm was not modified to use the new D-Bus fields. The
endianness issue is no problem for libnm, so there is little reason to
change it (at this point).
https://bugzilla.redhat.com/show_bug.cgi?id=1153559
https://bugzilla.redhat.com/show_bug.cgi?id=1584584
2018-07-13 20:15:33 +02:00
|
|
|
case PROP_WINS_SERVER_DATA:
|
|
|
|
|
g_variant_builder_init(&builder_data, G_VARIANT_TYPE("as"));
|
|
|
|
|
for (i = 0; i < priv->wins->len; i++) {
|
|
|
|
|
g_variant_builder_add(
|
|
|
|
|
&builder_data,
|
|
|
|
|
"s",
|
2020-01-09 11:29:27 +01:00
|
|
|
_nm_utils_inet4_ntop(g_array_index(priv->wins, in_addr_t, i), addr_str));
|
all: avoid byte ordering issue for IP4Config's Nameservers/WinsServers on D-Bus
Some properties in NetworkManager's D-Bus API are IPv4 addresses
in network byte order (big endian). That is problematic.
It is no problem, when the NetworkManager client runs on the same
host. That is the case with libnm, which does not support to be used
remotely for the time being.
It is a problem for an application that wants to access the D-Bus
interface of NetworkManager remotely. Possibly, such an application
would be implemented in two layers:
- one layer merely remotes D-Bus, without specific knowledge of
NetworkManager's API.
- a higher layer which accesses the remote D-Bus interface of NetworkManager.
Preferably it does so in an agnostic way, regardless of whether it runs
locally or remotely.
When using a D-Bus library, all accesses to 32 bit integers are in
native endianness (regardless of how the integer is actually encoded
on the lower layers). Likewise, D-Bus does not support annotating integer
types in non-native endianness. There is no way to annotate an integer
type "u" to be anything but native order.
That means, when remoting D-Bus at some point the endianness must be
corrected.
But by looking at the D-Bus introspection alone, it is not possible
to know which property need correction and which don't. One would need
to understand the meaning of the properties.
That makes it problematic, because the higher layer of the application,
which knows that the "Nameservers" property is supposed to be in network
order, might not easily know, whether it must correct for endianness.
Deprecate IP4Config properties that are only accessible with a particular
endianness, and add new properties that expose the same data in an
agnostic way.
Note that I added "WinsServerData" to be a plain "as", while
"NameserverData" is of type "aa{sv}". There is no particularly strong
reason for these choices, except that I could imagine that it could be
useful to expose additional information in the future about nameservers
(e.g. are they received via DHCP or manual configuration?). On the other
hand, WINS information likely won't get extended in the future.
Also note, libnm was not modified to use the new D-Bus fields. The
endianness issue is no problem for libnm, so there is little reason to
change it (at this point).
https://bugzilla.redhat.com/show_bug.cgi?id=1153559
https://bugzilla.redhat.com/show_bug.cgi?id=1584584
2018-07-13 20:15:33 +02:00
|
|
|
}
|
|
|
|
|
g_value_take_variant(value, g_variant_builder_end(&builder_data));
|
|
|
|
|
break;
|
2008-12-19 17:01:06 -05:00
|
|
|
case PROP_WINS_SERVERS:
|
2015-04-15 14:53:30 -04:00
|
|
|
g_value_take_variant(value,
|
|
|
|
|
g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
|
|
|
|
|
priv->wins->data,
|
|
|
|
|
priv->wins->len,
|
|
|
|
|
sizeof(guint32)));
|
2008-12-19 17:01:06 -05:00
|
|
|
break;
|
2007-02-16 11:23:49 +00:00
|
|
|
default:
|
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-20 16:31:10 -06:00
|
|
|
static void
|
|
|
|
|
set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
|
|
|
|
|
{
|
2016-01-04 16:51:04 +01:00
|
|
|
NMIP4Config * self = NM_IP4_CONFIG(object);
|
|
|
|
|
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2015-02-20 16:31:10 -06:00
|
|
|
switch (prop_id) {
|
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-06-12 08:16:47 +02:00
|
|
|
case PROP_MULTI_IDX:
|
|
|
|
|
/* construct-only */
|
|
|
|
|
priv->multi_idx = g_value_get_pointer(value);
|
|
|
|
|
if (!priv->multi_idx)
|
|
|
|
|
g_return_if_reached();
|
|
|
|
|
nm_dedup_multi_index_ref(priv->multi_idx);
|
|
|
|
|
break;
|
2015-02-20 16:31:10 -06:00
|
|
|
case PROP_IFINDEX:
|
2017-01-15 12:15:58 +01:00
|
|
|
/* construct-only */
|
2015-02-20 16:31:10 -06:00
|
|
|
priv->ifindex = g_value_get_int(value);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-01-15 12:15:58 +01:00
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
static void
|
2017-07-10 14:03:44 +02:00
|
|
|
nm_ip4_config_init(NMIP4Config *self)
|
2017-01-15 12:15:58 +01:00
|
|
|
{
|
2017-07-10 14:03:44 +02:00
|
|
|
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
2017-01-15 12:15:58 +01:00
|
|
|
|
2017-07-07 23:34:41 +02:00
|
|
|
nm_ip_config_dedup_multi_idx_type_init((NMIPConfigDedupMultiIdxType *) &priv->idx_ip4_addresses,
|
|
|
|
|
NMP_OBJECT_TYPE_IP4_ADDRESS);
|
2017-06-12 18:40:14 +02:00
|
|
|
nm_ip_config_dedup_multi_idx_type_init((NMIPConfigDedupMultiIdxType *) &priv->idx_ip4_routes,
|
|
|
|
|
NMP_OBJECT_TYPE_IP4_ROUTE);
|
|
|
|
|
|
core: implement setting MDNS setting for systemd
The connection.mdns setting is a per-connection setting,
so one might expect that one activated device can only have
one MDNS setting at a time.
However, with certain VPN plugins (those that don't have their
own IP interface, like libreswan), the VPN configuration is merged
into the configuration of the device. So, in this case, there
might be multiple settings for one device that must be merged.
We already have a mechanism for that. It's NMIP4Config. Let NMIP4Config
track this piece of information. Although, stricitly speaking this
is not tied to IPv4, the alternative would be to introduce a new
object to track such data, which would be a tremendous effort
and more complicated then this.
Luckily, NMDnsManager and NMDnsPlugin are already equipped to
handle multiple NMIPConfig instances per device (IPv4 vs. IPv6,
and Device vs. VPN).
Also make "connection.mdns" configurable via global defaults in
NetworkManager.conf.
2017-12-20 14:49:32 +01:00
|
|
|
priv->mdns = NM_SETTING_CONNECTION_MDNS_DEFAULT;
|
2018-08-31 15:14:39 +02:00
|
|
|
priv->llmnr = NM_SETTING_CONNECTION_LLMNR_DEFAULT;
|
2017-01-15 12:15:58 +01:00
|
|
|
priv->nameservers = g_array_new(FALSE, FALSE, sizeof(guint32));
|
|
|
|
|
priv->domains = g_ptr_array_new_with_free_func(g_free);
|
|
|
|
|
priv->searches = g_ptr_array_new_with_free_func(g_free);
|
|
|
|
|
priv->dns_options = g_ptr_array_new_with_free_func(g_free);
|
|
|
|
|
priv->nis = g_array_new(FALSE, TRUE, sizeof(guint32));
|
|
|
|
|
priv->wins = g_array_new(FALSE, TRUE, sizeof(guint32));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NMIP4Config *
|
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-06-12 08:16:47 +02:00
|
|
|
nm_ip4_config_new(NMDedupMultiIndex *multi_idx, int ifindex)
|
2017-01-15 12:15:58 +01:00
|
|
|
{
|
|
|
|
|
g_return_val_if_fail(ifindex >= -1, NULL);
|
2020-11-12 15:57:06 +01:00
|
|
|
return g_object_new(NM_TYPE_IP4_CONFIG,
|
|
|
|
|
NM_IP4_CONFIG_MULTI_IDX,
|
|
|
|
|
multi_idx,
|
|
|
|
|
NM_IP4_CONFIG_IFINDEX,
|
|
|
|
|
ifindex,
|
|
|
|
|
NULL);
|
2017-01-15 12:15:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
finalize(GObject *object)
|
|
|
|
|
{
|
|
|
|
|
NMIP4Config * self = NM_IP4_CONFIG(object);
|
|
|
|
|
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
|
|
|
|
|
|
2017-08-31 13:39:04 +02:00
|
|
|
nm_clear_nmp_object(&priv->best_default_route);
|
|
|
|
|
|
2017-07-07 23:34:41 +02:00
|
|
|
nm_dedup_multi_index_remove_idx(priv->multi_idx, &priv->idx_ip4_addresses);
|
2017-06-12 18:40:14 +02:00
|
|
|
nm_dedup_multi_index_remove_idx(priv->multi_idx, &priv->idx_ip4_routes);
|
|
|
|
|
|
2017-01-15 12:15:58 +01:00
|
|
|
nm_clear_g_variant(&priv->address_data_variant);
|
|
|
|
|
nm_clear_g_variant(&priv->addresses_variant);
|
2017-07-11 13:20:23 +02:00
|
|
|
nm_clear_g_variant(&priv->route_data_variant);
|
|
|
|
|
nm_clear_g_variant(&priv->routes_variant);
|
|
|
|
|
|
2017-01-15 12:15:58 +01:00
|
|
|
g_array_unref(priv->nameservers);
|
|
|
|
|
g_ptr_array_unref(priv->domains);
|
|
|
|
|
g_ptr_array_unref(priv->searches);
|
|
|
|
|
g_ptr_array_unref(priv->dns_options);
|
|
|
|
|
g_array_unref(priv->nis);
|
|
|
|
|
g_free(priv->nis_domain);
|
|
|
|
|
g_array_unref(priv->wins);
|
|
|
|
|
|
|
|
|
|
G_OBJECT_CLASS(nm_ip4_config_parent_class)->finalize(object);
|
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-06-12 08:16:47 +02:00
|
|
|
|
|
|
|
|
nm_dedup_multi_index_unref(priv->multi_idx);
|
2017-01-15 12:15:58 +01:00
|
|
|
}
|
|
|
|
|
|
core/dbus: rework D-Bus implementation to use lower layer GDBusConnection API
Previously, we used the generated GDBusInterfaceSkeleton types and glued
them via the NMExportedObject base class to our NM types. We also used
GDBusObjectManagerServer.
Don't do that anymore. The resulting code was more complicated despite (or
because?) using generated classes. It was hard to understand, complex, had
ordering-issues, and had a runtime and memory overhead.
This patch refactors this entirely and uses the lower layer API GDBusConnection
directly. It replaces the generated code, GDBusInterfaceSkeleton, and
GDBusObjectManagerServer. All this is now done by NMDbusObject and NMDBusManager
and static descriptor instances of type GDBusInterfaceInfo.
This adds a net plus of more then 1300 lines of hand written code. I claim
that this implementation is easier to understand. Note that previously we
also required extensive and complex glue code to bind our objects to the
generated skeleton objects. Instead, now glue our objects directly to
GDBusConnection. The result is more immediate and gets rid of layers of
code in between.
Now that the D-Bus glue us more under our control, we can address issus and
bottlenecks better, instead of adding code to bend the generated skeletons
to our needs.
Note that the current implementation now only supports one D-Bus connection.
That was effectively the case already, although there were places (and still are)
where the code pretends it could also support connections from a private socket.
We dropped private socket support mainly because it was unused, untested and
buggy, but also because GDBusObjectManagerServer could not export the same
objects on multiple connections. Now, it would be rather straight forward to
fix that and re-introduce ObjectManager on each private connection. But this
commit doesn't do that yet, and the new code intentionally supports only one
D-Bus connection.
Also, the D-Bus startup was simplified. There is no retry, either nm_dbus_manager_start()
succeeds, or it detects the initrd case. In the initrd case, bus manager never tries to
connect to D-Bus. Since the initrd scenario is not yet used/tested, this is good enough
for the moment. It could be easily extended later, for example with polling whether the
system bus appears (like was done previously). Also, restart of D-Bus daemon isn't
supported either -- just like before.
Note how NMDBusManager now implements the ObjectManager D-Bus interface
directly.
Also, this fixes race issues in the server, by no longer delaying
PropertiesChanged signals. NMExportedObject would collect changed
properties and send the signal out in idle_emit_properties_changed()
on idle. This messes up the ordering of change events w.r.t. other
signals and events on the bus. Note that not only NMExportedObject
messed up the ordering. Also the generated code would hook into
notify() and process change events in and idle handle, exhibiting the
same ordering issue too.
No longer do that. PropertiesChanged signals will be sent right away
by hooking into dispatch_properties_changed(). This means, changing
a property in quick succession will no longer be combined and is
guaranteed to emit signals for each individual state. Quite possibly
we emit now more PropertiesChanged signals then before.
However, we are now able to group a set of changes by using standard
g_object_freeze_notify()/g_object_thaw_notify(). We probably should
make more use of that.
Also, now that our signals are all handled in the right order, we
might find places where we still emit them in the wrong order. But that
is then due to the order in which our GObjects emit signals, not due
to an ill behavior of the D-Bus glue. Possibly we need to identify
such ordering issues and fix them.
Numbers (for contrib/rpm --without debug on x86_64):
- the patch changes the code size of NetworkManager by
- 2809360 bytes
+ 2537528 bytes (-9.7%)
- Runtime measurements are harder because there is a large variance
during testing. In other words, the numbers are not reproducible.
Currently, the implementation performs no caching of GVariants at all,
but it would be rather simple to add it, if that turns out to be
useful.
Anyway, without strong claim, it seems that the new form tends to
perform slightly better. That would be no surprise.
$ time (for i in {1..1000}; do nmcli >/dev/null || break; echo -n .; done)
- real 1m39.355s
+ real 1m37.432s
$ time (for i in {1..2000}; do busctl call org.freedesktop.NetworkManager /org/freedesktop org.freedesktop.DBus.ObjectManager GetManagedObjects > /dev/null || break; echo -n .; done)
- real 0m26.843s
+ real 0m25.281s
- Regarding RSS size, just looking at the processes in similar
conditions, doesn't give a large difference. On my system they
consume about 19MB RSS. It seems that the new version has a
slightly smaller RSS size.
- 19356 RSS
+ 18660 RSS
2018-02-26 13:51:52 +01:00
|
|
|
static const NMDBusInterfaceInfoExtended interface_info_ip4_config = {
|
|
|
|
|
.parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT(
|
|
|
|
|
NM_DBUS_INTERFACE_IP4_CONFIG,
|
|
|
|
|
.signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ),
|
|
|
|
|
.properties = NM_DEFINE_GDBUS_PROPERTY_INFOS(
|
all: avoid byte ordering issue for IP4Config's Nameservers/WinsServers on D-Bus
Some properties in NetworkManager's D-Bus API are IPv4 addresses
in network byte order (big endian). That is problematic.
It is no problem, when the NetworkManager client runs on the same
host. That is the case with libnm, which does not support to be used
remotely for the time being.
It is a problem for an application that wants to access the D-Bus
interface of NetworkManager remotely. Possibly, such an application
would be implemented in two layers:
- one layer merely remotes D-Bus, without specific knowledge of
NetworkManager's API.
- a higher layer which accesses the remote D-Bus interface of NetworkManager.
Preferably it does so in an agnostic way, regardless of whether it runs
locally or remotely.
When using a D-Bus library, all accesses to 32 bit integers are in
native endianness (regardless of how the integer is actually encoded
on the lower layers). Likewise, D-Bus does not support annotating integer
types in non-native endianness. There is no way to annotate an integer
type "u" to be anything but native order.
That means, when remoting D-Bus at some point the endianness must be
corrected.
But by looking at the D-Bus introspection alone, it is not possible
to know which property need correction and which don't. One would need
to understand the meaning of the properties.
That makes it problematic, because the higher layer of the application,
which knows that the "Nameservers" property is supposed to be in network
order, might not easily know, whether it must correct for endianness.
Deprecate IP4Config properties that are only accessible with a particular
endianness, and add new properties that expose the same data in an
agnostic way.
Note that I added "WinsServerData" to be a plain "as", while
"NameserverData" is of type "aa{sv}". There is no particularly strong
reason for these choices, except that I could imagine that it could be
useful to expose additional information in the future about nameservers
(e.g. are they received via DHCP or manual configuration?). On the other
hand, WINS information likely won't get extended in the future.
Also note, libnm was not modified to use the new D-Bus fields. The
endianness issue is no problem for libnm, so there is little reason to
change it (at this point).
https://bugzilla.redhat.com/show_bug.cgi?id=1153559
https://bugzilla.redhat.com/show_bug.cgi?id=1584584
2018-07-13 20:15:33 +02:00
|
|
|
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Addresses",
|
|
|
|
|
"aau",
|
|
|
|
|
NM_IP4_CONFIG_ADDRESSES),
|
|
|
|
|
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("AddressData",
|
|
|
|
|
"aa{sv}",
|
|
|
|
|
NM_IP4_CONFIG_ADDRESS_DATA),
|
|
|
|
|
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Gateway", "s", NM_IP4_CONFIG_GATEWAY),
|
|
|
|
|
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Routes", "aau", NM_IP4_CONFIG_ROUTES),
|
|
|
|
|
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("RouteData",
|
|
|
|
|
"aa{sv}",
|
|
|
|
|
NM_IP4_CONFIG_ROUTE_DATA),
|
|
|
|
|
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("NameserverData",
|
|
|
|
|
"aa{sv}",
|
|
|
|
|
NM_IP4_CONFIG_NAMESERVER_DATA),
|
|
|
|
|
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Nameservers",
|
|
|
|
|
"au",
|
|
|
|
|
NM_IP4_CONFIG_NAMESERVERS),
|
|
|
|
|
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Domains",
|
|
|
|
|
"as",
|
|
|
|
|
NM_IP4_CONFIG_DOMAINS),
|
|
|
|
|
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Searches",
|
|
|
|
|
"as",
|
|
|
|
|
NM_IP4_CONFIG_SEARCHES),
|
|
|
|
|
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("DnsOptions",
|
|
|
|
|
"as",
|
|
|
|
|
NM_IP4_CONFIG_DNS_OPTIONS),
|
|
|
|
|
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("DnsPriority",
|
|
|
|
|
"i",
|
|
|
|
|
NM_IP4_CONFIG_DNS_PRIORITY),
|
|
|
|
|
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("WinsServerData",
|
|
|
|
|
"as",
|
|
|
|
|
NM_IP4_CONFIG_WINS_SERVER_DATA),
|
|
|
|
|
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("WinsServers",
|
|
|
|
|
"au",
|
|
|
|
|
NM_IP4_CONFIG_WINS_SERVERS), ), ),
|
core/dbus: rework D-Bus implementation to use lower layer GDBusConnection API
Previously, we used the generated GDBusInterfaceSkeleton types and glued
them via the NMExportedObject base class to our NM types. We also used
GDBusObjectManagerServer.
Don't do that anymore. The resulting code was more complicated despite (or
because?) using generated classes. It was hard to understand, complex, had
ordering-issues, and had a runtime and memory overhead.
This patch refactors this entirely and uses the lower layer API GDBusConnection
directly. It replaces the generated code, GDBusInterfaceSkeleton, and
GDBusObjectManagerServer. All this is now done by NMDbusObject and NMDBusManager
and static descriptor instances of type GDBusInterfaceInfo.
This adds a net plus of more then 1300 lines of hand written code. I claim
that this implementation is easier to understand. Note that previously we
also required extensive and complex glue code to bind our objects to the
generated skeleton objects. Instead, now glue our objects directly to
GDBusConnection. The result is more immediate and gets rid of layers of
code in between.
Now that the D-Bus glue us more under our control, we can address issus and
bottlenecks better, instead of adding code to bend the generated skeletons
to our needs.
Note that the current implementation now only supports one D-Bus connection.
That was effectively the case already, although there were places (and still are)
where the code pretends it could also support connections from a private socket.
We dropped private socket support mainly because it was unused, untested and
buggy, but also because GDBusObjectManagerServer could not export the same
objects on multiple connections. Now, it would be rather straight forward to
fix that and re-introduce ObjectManager on each private connection. But this
commit doesn't do that yet, and the new code intentionally supports only one
D-Bus connection.
Also, the D-Bus startup was simplified. There is no retry, either nm_dbus_manager_start()
succeeds, or it detects the initrd case. In the initrd case, bus manager never tries to
connect to D-Bus. Since the initrd scenario is not yet used/tested, this is good enough
for the moment. It could be easily extended later, for example with polling whether the
system bus appears (like was done previously). Also, restart of D-Bus daemon isn't
supported either -- just like before.
Note how NMDBusManager now implements the ObjectManager D-Bus interface
directly.
Also, this fixes race issues in the server, by no longer delaying
PropertiesChanged signals. NMExportedObject would collect changed
properties and send the signal out in idle_emit_properties_changed()
on idle. This messes up the ordering of change events w.r.t. other
signals and events on the bus. Note that not only NMExportedObject
messed up the ordering. Also the generated code would hook into
notify() and process change events in and idle handle, exhibiting the
same ordering issue too.
No longer do that. PropertiesChanged signals will be sent right away
by hooking into dispatch_properties_changed(). This means, changing
a property in quick succession will no longer be combined and is
guaranteed to emit signals for each individual state. Quite possibly
we emit now more PropertiesChanged signals then before.
However, we are now able to group a set of changes by using standard
g_object_freeze_notify()/g_object_thaw_notify(). We probably should
make more use of that.
Also, now that our signals are all handled in the right order, we
might find places where we still emit them in the wrong order. But that
is then due to the order in which our GObjects emit signals, not due
to an ill behavior of the D-Bus glue. Possibly we need to identify
such ordering issues and fix them.
Numbers (for contrib/rpm --without debug on x86_64):
- the patch changes the code size of NetworkManager by
- 2809360 bytes
+ 2537528 bytes (-9.7%)
- Runtime measurements are harder because there is a large variance
during testing. In other words, the numbers are not reproducible.
Currently, the implementation performs no caching of GVariants at all,
but it would be rather simple to add it, if that turns out to be
useful.
Anyway, without strong claim, it seems that the new form tends to
perform slightly better. That would be no surprise.
$ time (for i in {1..1000}; do nmcli >/dev/null || break; echo -n .; done)
- real 1m39.355s
+ real 1m37.432s
$ time (for i in {1..2000}; do busctl call org.freedesktop.NetworkManager /org/freedesktop org.freedesktop.DBus.ObjectManager GetManagedObjects > /dev/null || break; echo -n .; done)
- real 0m26.843s
+ real 0m25.281s
- Regarding RSS size, just looking at the processes in similar
conditions, doesn't give a large difference. On my system they
consume about 19MB RSS. It seems that the new version has a
slightly smaller RSS size.
- 19356 RSS
+ 18660 RSS
2018-02-26 13:51:52 +01:00
|
|
|
.legacy_property_changed = TRUE,
|
|
|
|
|
};
|
|
|
|
|
|
2007-02-16 11:23:49 +00:00
|
|
|
static void
|
2020-07-29 19:30:22 +02:00
|
|
|
nm_ip4_config_class_init(NMIP4ConfigClass *klass)
|
2007-02-16 11:23:49 +00:00
|
|
|
{
|
2020-07-29 19:30:22 +02:00
|
|
|
GObjectClass * object_class = G_OBJECT_CLASS(klass);
|
|
|
|
|
NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass);
|
|
|
|
|
NMIPConfigClass * ip_config_class = NM_IP_CONFIG_CLASS(klass);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-07-29 19:30:22 +02:00
|
|
|
ip_config_class->is_ipv4 = TRUE;
|
|
|
|
|
ip_config_class->addr_family = AF_INET;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2018-03-13 10:14:06 +01:00
|
|
|
dbus_object_class->export_path = NM_DBUS_EXPORT_PATH_NUMBERED(NM_DBUS_PATH "/IP4Config");
|
core/dbus: rework D-Bus implementation to use lower layer GDBusConnection API
Previously, we used the generated GDBusInterfaceSkeleton types and glued
them via the NMExportedObject base class to our NM types. We also used
GDBusObjectManagerServer.
Don't do that anymore. The resulting code was more complicated despite (or
because?) using generated classes. It was hard to understand, complex, had
ordering-issues, and had a runtime and memory overhead.
This patch refactors this entirely and uses the lower layer API GDBusConnection
directly. It replaces the generated code, GDBusInterfaceSkeleton, and
GDBusObjectManagerServer. All this is now done by NMDbusObject and NMDBusManager
and static descriptor instances of type GDBusInterfaceInfo.
This adds a net plus of more then 1300 lines of hand written code. I claim
that this implementation is easier to understand. Note that previously we
also required extensive and complex glue code to bind our objects to the
generated skeleton objects. Instead, now glue our objects directly to
GDBusConnection. The result is more immediate and gets rid of layers of
code in between.
Now that the D-Bus glue us more under our control, we can address issus and
bottlenecks better, instead of adding code to bend the generated skeletons
to our needs.
Note that the current implementation now only supports one D-Bus connection.
That was effectively the case already, although there were places (and still are)
where the code pretends it could also support connections from a private socket.
We dropped private socket support mainly because it was unused, untested and
buggy, but also because GDBusObjectManagerServer could not export the same
objects on multiple connections. Now, it would be rather straight forward to
fix that and re-introduce ObjectManager on each private connection. But this
commit doesn't do that yet, and the new code intentionally supports only one
D-Bus connection.
Also, the D-Bus startup was simplified. There is no retry, either nm_dbus_manager_start()
succeeds, or it detects the initrd case. In the initrd case, bus manager never tries to
connect to D-Bus. Since the initrd scenario is not yet used/tested, this is good enough
for the moment. It could be easily extended later, for example with polling whether the
system bus appears (like was done previously). Also, restart of D-Bus daemon isn't
supported either -- just like before.
Note how NMDBusManager now implements the ObjectManager D-Bus interface
directly.
Also, this fixes race issues in the server, by no longer delaying
PropertiesChanged signals. NMExportedObject would collect changed
properties and send the signal out in idle_emit_properties_changed()
on idle. This messes up the ordering of change events w.r.t. other
signals and events on the bus. Note that not only NMExportedObject
messed up the ordering. Also the generated code would hook into
notify() and process change events in and idle handle, exhibiting the
same ordering issue too.
No longer do that. PropertiesChanged signals will be sent right away
by hooking into dispatch_properties_changed(). This means, changing
a property in quick succession will no longer be combined and is
guaranteed to emit signals for each individual state. Quite possibly
we emit now more PropertiesChanged signals then before.
However, we are now able to group a set of changes by using standard
g_object_freeze_notify()/g_object_thaw_notify(). We probably should
make more use of that.
Also, now that our signals are all handled in the right order, we
might find places where we still emit them in the wrong order. But that
is then due to the order in which our GObjects emit signals, not due
to an ill behavior of the D-Bus glue. Possibly we need to identify
such ordering issues and fix them.
Numbers (for contrib/rpm --without debug on x86_64):
- the patch changes the code size of NetworkManager by
- 2809360 bytes
+ 2537528 bytes (-9.7%)
- Runtime measurements are harder because there is a large variance
during testing. In other words, the numbers are not reproducible.
Currently, the implementation performs no caching of GVariants at all,
but it would be rather simple to add it, if that turns out to be
useful.
Anyway, without strong claim, it seems that the new form tends to
perform slightly better. That would be no surprise.
$ time (for i in {1..1000}; do nmcli >/dev/null || break; echo -n .; done)
- real 1m39.355s
+ real 1m37.432s
$ time (for i in {1..2000}; do busctl call org.freedesktop.NetworkManager /org/freedesktop org.freedesktop.DBus.ObjectManager GetManagedObjects > /dev/null || break; echo -n .; done)
- real 0m26.843s
+ real 0m25.281s
- Regarding RSS size, just looking at the processes in similar
conditions, doesn't give a large difference. On my system they
consume about 19MB RSS. It seems that the new version has a
slightly smaller RSS size.
- 19356 RSS
+ 18660 RSS
2018-02-26 13:51:52 +01:00
|
|
|
dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_ip4_config);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2007-02-16 11:23:49 +00:00
|
|
|
object_class->get_property = get_property;
|
2015-02-20 16:31:10 -06:00
|
|
|
object_class->set_property = set_property;
|
2007-02-16 11:23:49 +00:00
|
|
|
object_class->finalize = finalize;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
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-06-12 08:16:47 +02:00
|
|
|
obj_properties[PROP_MULTI_IDX] =
|
|
|
|
|
g_param_spec_pointer(NM_IP4_CONFIG_MULTI_IDX,
|
|
|
|
|
"",
|
|
|
|
|
"",
|
|
|
|
|
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
|
2015-02-20 16:31:10 -06:00
|
|
|
obj_properties[PROP_IFINDEX] =
|
2016-07-06 10:20:06 +02:00
|
|
|
g_param_spec_int(NM_IP4_CONFIG_IFINDEX,
|
|
|
|
|
"",
|
|
|
|
|
"",
|
|
|
|
|
-1,
|
|
|
|
|
G_MAXINT,
|
|
|
|
|
-1,
|
|
|
|
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
|
libnm-core, libnm, core: add AddressData and RouteData properties
Add AddressData and RouteData properties to NMSettingIPConfig and
NMIP[46]Config. These are like the existing "addresses" and "routes"
properties, but using strings and containing additional attributes,
like NMIPAddress and NMIPRoute.
This only affects the D-Bus representations; there are no API changes
to NMSettingIP{,4,6}Config or NMIP{4,6}Config as a result of this; the
additional information is just added to the existing 'addresses' and
'routes' properties.
NMSettingIP4Config and NMSettingIP6Config now always generate both
old-style data ('addresses', 'address-labels', 'routes') and new-style
data ('address-data', 'gateway', 'route-data') when serializing to
D-Bus, for backward compatibility. When deserializing, they will fill
in the 'addresses' and 'routes' properties from the new-style data if
it is present (ignoring the old-style data), or from the old-style
data if the new-style isn't present.
The daemon-side NMIP4Config and NMIP6Config always emit changes for
both 'Addresses'/'Routes' and 'AddressData'/'RouteData'. The
libnm-side classes initially listen for changes on both properties,
but start ignoring the 'Addresses' and 'Routes' properties once they
know the daemon is also providing 'AddressData' and 'RouteData'.
2014-10-21 08:33:18 -04:00
|
|
|
obj_properties[PROP_ADDRESS_DATA] =
|
2016-07-06 10:20:06 +02:00
|
|
|
g_param_spec_variant(NM_IP4_CONFIG_ADDRESS_DATA,
|
|
|
|
|
"",
|
|
|
|
|
"",
|
|
|
|
|
G_VARIANT_TYPE("aa{sv}"),
|
|
|
|
|
NULL,
|
|
|
|
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
2013-09-06 11:56:41 +02:00
|
|
|
obj_properties[PROP_ADDRESSES] =
|
2016-07-06 10:20:06 +02:00
|
|
|
g_param_spec_variant(NM_IP4_CONFIG_ADDRESSES,
|
|
|
|
|
"",
|
|
|
|
|
"",
|
|
|
|
|
G_VARIANT_TYPE("aau"),
|
|
|
|
|
NULL,
|
|
|
|
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
libnm-core, libnm, core: add AddressData and RouteData properties
Add AddressData and RouteData properties to NMSettingIPConfig and
NMIP[46]Config. These are like the existing "addresses" and "routes"
properties, but using strings and containing additional attributes,
like NMIPAddress and NMIPRoute.
This only affects the D-Bus representations; there are no API changes
to NMSettingIP{,4,6}Config or NMIP{4,6}Config as a result of this; the
additional information is just added to the existing 'addresses' and
'routes' properties.
NMSettingIP4Config and NMSettingIP6Config now always generate both
old-style data ('addresses', 'address-labels', 'routes') and new-style
data ('address-data', 'gateway', 'route-data') when serializing to
D-Bus, for backward compatibility. When deserializing, they will fill
in the 'addresses' and 'routes' properties from the new-style data if
it is present (ignoring the old-style data), or from the old-style
data if the new-style isn't present.
The daemon-side NMIP4Config and NMIP6Config always emit changes for
both 'Addresses'/'Routes' and 'AddressData'/'RouteData'. The
libnm-side classes initially listen for changes on both properties,
but start ignoring the 'Addresses' and 'Routes' properties once they
know the daemon is also providing 'AddressData' and 'RouteData'.
2014-10-21 08:33:18 -04:00
|
|
|
obj_properties[PROP_ROUTE_DATA] =
|
2016-07-06 10:20:06 +02:00
|
|
|
g_param_spec_variant(NM_IP4_CONFIG_ROUTE_DATA,
|
|
|
|
|
"",
|
|
|
|
|
"",
|
|
|
|
|
G_VARIANT_TYPE("aa{sv}"),
|
|
|
|
|
NULL,
|
|
|
|
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
|
|
|
|
obj_properties[PROP_ROUTES] = g_param_spec_variant(NM_IP4_CONFIG_ROUTES,
|
|
|
|
|
"",
|
|
|
|
|
"",
|
|
|
|
|
G_VARIANT_TYPE("aau"),
|
|
|
|
|
NULL,
|
|
|
|
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
|
|
|
|
obj_properties[PROP_GATEWAY] = g_param_spec_string(NM_IP4_CONFIG_GATEWAY,
|
|
|
|
|
"",
|
|
|
|
|
"",
|
|
|
|
|
NULL,
|
|
|
|
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
all: avoid byte ordering issue for IP4Config's Nameservers/WinsServers on D-Bus
Some properties in NetworkManager's D-Bus API are IPv4 addresses
in network byte order (big endian). That is problematic.
It is no problem, when the NetworkManager client runs on the same
host. That is the case with libnm, which does not support to be used
remotely for the time being.
It is a problem for an application that wants to access the D-Bus
interface of NetworkManager remotely. Possibly, such an application
would be implemented in two layers:
- one layer merely remotes D-Bus, without specific knowledge of
NetworkManager's API.
- a higher layer which accesses the remote D-Bus interface of NetworkManager.
Preferably it does so in an agnostic way, regardless of whether it runs
locally or remotely.
When using a D-Bus library, all accesses to 32 bit integers are in
native endianness (regardless of how the integer is actually encoded
on the lower layers). Likewise, D-Bus does not support annotating integer
types in non-native endianness. There is no way to annotate an integer
type "u" to be anything but native order.
That means, when remoting D-Bus at some point the endianness must be
corrected.
But by looking at the D-Bus introspection alone, it is not possible
to know which property need correction and which don't. One would need
to understand the meaning of the properties.
That makes it problematic, because the higher layer of the application,
which knows that the "Nameservers" property is supposed to be in network
order, might not easily know, whether it must correct for endianness.
Deprecate IP4Config properties that are only accessible with a particular
endianness, and add new properties that expose the same data in an
agnostic way.
Note that I added "WinsServerData" to be a plain "as", while
"NameserverData" is of type "aa{sv}". There is no particularly strong
reason for these choices, except that I could imagine that it could be
useful to expose additional information in the future about nameservers
(e.g. are they received via DHCP or manual configuration?). On the other
hand, WINS information likely won't get extended in the future.
Also note, libnm was not modified to use the new D-Bus fields. The
endianness issue is no problem for libnm, so there is little reason to
change it (at this point).
https://bugzilla.redhat.com/show_bug.cgi?id=1153559
https://bugzilla.redhat.com/show_bug.cgi?id=1584584
2018-07-13 20:15:33 +02:00
|
|
|
obj_properties[PROP_NAMESERVER_DATA] =
|
|
|
|
|
g_param_spec_variant(NM_IP4_CONFIG_NAMESERVER_DATA,
|
|
|
|
|
"",
|
|
|
|
|
"",
|
|
|
|
|
G_VARIANT_TYPE("aa{sv}"),
|
|
|
|
|
NULL,
|
|
|
|
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
2013-09-06 11:56:41 +02:00
|
|
|
obj_properties[PROP_NAMESERVERS] =
|
2016-07-06 10:20:06 +02:00
|
|
|
g_param_spec_variant(NM_IP4_CONFIG_NAMESERVERS,
|
|
|
|
|
"",
|
|
|
|
|
"",
|
|
|
|
|
G_VARIANT_TYPE("au"),
|
|
|
|
|
NULL,
|
|
|
|
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
|
|
|
|
obj_properties[PROP_DOMAINS] = g_param_spec_boxed(NM_IP4_CONFIG_DOMAINS,
|
|
|
|
|
"",
|
|
|
|
|
"",
|
|
|
|
|
G_TYPE_STRV,
|
|
|
|
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
|
|
|
|
obj_properties[PROP_SEARCHES] = g_param_spec_boxed(NM_IP4_CONFIG_SEARCHES,
|
|
|
|
|
"",
|
|
|
|
|
"",
|
|
|
|
|
G_TYPE_STRV,
|
|
|
|
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
2015-03-26 09:23:12 +01:00
|
|
|
obj_properties[PROP_DNS_OPTIONS] =
|
2016-07-06 10:20:06 +02:00
|
|
|
g_param_spec_boxed(NM_IP4_CONFIG_DNS_OPTIONS,
|
|
|
|
|
"",
|
|
|
|
|
"",
|
|
|
|
|
G_TYPE_STRV,
|
|
|
|
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
|
|
|
|
obj_properties[PROP_DNS_PRIORITY] = g_param_spec_int(NM_IP4_CONFIG_DNS_PRIORITY,
|
|
|
|
|
"",
|
|
|
|
|
"",
|
|
|
|
|
G_MININT32,
|
|
|
|
|
G_MAXINT32,
|
|
|
|
|
0,
|
|
|
|
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
all: avoid byte ordering issue for IP4Config's Nameservers/WinsServers on D-Bus
Some properties in NetworkManager's D-Bus API are IPv4 addresses
in network byte order (big endian). That is problematic.
It is no problem, when the NetworkManager client runs on the same
host. That is the case with libnm, which does not support to be used
remotely for the time being.
It is a problem for an application that wants to access the D-Bus
interface of NetworkManager remotely. Possibly, such an application
would be implemented in two layers:
- one layer merely remotes D-Bus, without specific knowledge of
NetworkManager's API.
- a higher layer which accesses the remote D-Bus interface of NetworkManager.
Preferably it does so in an agnostic way, regardless of whether it runs
locally or remotely.
When using a D-Bus library, all accesses to 32 bit integers are in
native endianness (regardless of how the integer is actually encoded
on the lower layers). Likewise, D-Bus does not support annotating integer
types in non-native endianness. There is no way to annotate an integer
type "u" to be anything but native order.
That means, when remoting D-Bus at some point the endianness must be
corrected.
But by looking at the D-Bus introspection alone, it is not possible
to know which property need correction and which don't. One would need
to understand the meaning of the properties.
That makes it problematic, because the higher layer of the application,
which knows that the "Nameservers" property is supposed to be in network
order, might not easily know, whether it must correct for endianness.
Deprecate IP4Config properties that are only accessible with a particular
endianness, and add new properties that expose the same data in an
agnostic way.
Note that I added "WinsServerData" to be a plain "as", while
"NameserverData" is of type "aa{sv}". There is no particularly strong
reason for these choices, except that I could imagine that it could be
useful to expose additional information in the future about nameservers
(e.g. are they received via DHCP or manual configuration?). On the other
hand, WINS information likely won't get extended in the future.
Also note, libnm was not modified to use the new D-Bus fields. The
endianness issue is no problem for libnm, so there is little reason to
change it (at this point).
https://bugzilla.redhat.com/show_bug.cgi?id=1153559
https://bugzilla.redhat.com/show_bug.cgi?id=1584584
2018-07-13 20:15:33 +02:00
|
|
|
obj_properties[PROP_WINS_SERVER_DATA] =
|
|
|
|
|
g_param_spec_variant(NM_IP4_CONFIG_WINS_SERVER_DATA,
|
|
|
|
|
"",
|
|
|
|
|
"",
|
|
|
|
|
G_VARIANT_TYPE("as"),
|
|
|
|
|
NULL,
|
|
|
|
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
2013-09-06 11:56:41 +02:00
|
|
|
obj_properties[PROP_WINS_SERVERS] =
|
2016-07-06 10:20:06 +02:00
|
|
|
g_param_spec_variant(NM_IP4_CONFIG_WINS_SERVERS,
|
|
|
|
|
"",
|
|
|
|
|
"",
|
|
|
|
|
G_VARIANT_TYPE("au"),
|
|
|
|
|
NULL,
|
|
|
|
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2016-01-19 16:45:55 +01:00
|
|
|
g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties);
|
2007-02-16 11:23:49 +00:00
|
|
|
}
|