summaryrefslogtreecommitdiff
path: root/src/nm-ip6-config.c
Commit message (Collapse)AuthorAgeFilesLines
* all: move "src/" directory to "src/core/"Thomas Haller2021-02-041-2750/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | Currently "src/" mostly contains the source code of the daemon. I say mostly, because that is not true, there are also the device, settings, wwan, ppp plugins, the initrd generator, the pppd and dhcp helper, and probably more. Also we have source code under libnm-core/, libnm/, clients/, and shared/ directories. That is all confusing. We should have one "src" directory, that contains subdirectories. Those subdirectories should contain individual parts (libraries or applications), that possibly have dependencies on other subdirectories. There should be a flat hierarchy of directories under src/, which contains individual modules. As the name "src/" is already taken, that prevents any sensible restructuring of the code. As a first step, move "src/" to "src/core/". This gives space to reorganize the code better by moving individual components into "src/". For inspiration, look at systemd's "src/" directory. https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/743
* ndisc: track expiry of Router Advertisements in millisecondsThomas Haller2021-01-271-3/+18
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Elements of RAs have a lifetime. Previously we would track both the timestamp (when we received the RA) and the lifetime. However, we are mainly interested in the expiry time. So tracking the expiry in form of timestamp and lifetime is redundant and cumbersome to use. Consider also the cases nm_ndisc_add_address() were we mangle the expiry. In that case, the timestamp becomes meaningless or it's not clear what the timestamp should be. Also, there are no real cases where we actually need the receive timestamp. Note that when we convert the times to NMPlatformIP6Address, we again need to synthesize a base time stamp. But here too, it's NMPlatformIP6Address fault of doing this pointless split of timestamp and lifetime. While at it, increase the precision to milliseconds. As we receive lifetimes with seconds precision, one might think that seconds precision is enough for tracking the timeouts. However it just leads to ugly uncertainty about rounding, when we can track times with sufficient precision without downside. For example, before configuring an address in kernel, we also need to calculate a remaining lifetime with a lower precision. By having the exact values, we can do so more accurately. At least, in theory. Of course NMPlatformIP6Address itself has only precision of seconds, we already loose the information before. However, NMNDisc no longer has that problem.
* platform: move "nm-platform-utils.[hc]" to "shared/nm-platform" libraryThomas Haller2021-01-151-1/+1
| | | | | By now it has no further dependencies on libnm-core or NetworkManager core. Make it part of "shared/nm-platform" library.
* core: replace g_return_if_fail() with nm_assert() in ↵Thomas Haller2021-01-131-2/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | nm_ip_config_iter_ip[46]_(address,route)_init() With LTO, the compiler can see that some code paths return without initializing the variable. But it fails to see that those are code paths after an assertion fail. Still that can lead to "-Wmaybe-uninitialized" warnings in the caller. Avoid that by not using g_return_if_fail() but nm_assert(). src/nm-ip6-config.c: In function '_nmtst_ip6_config_get_address': ./shared/nm-glib-aux/nm-dedup-multi.h:337:8: error: 'iter._next' may be used uninitialized in this function [-Werror=maybe-uninitialized] 337 | if (!iter->_next) | ^ src/nm-ip6-config.c:1622:33: note: 'iter._next' was declared here 1622 | NMDedupMultiIter iter; | ^ ./shared/nm-glib-aux/nm-dedup-multi.h:343:8: error: 'iter._head' may be used uninitialized in this function [-Werror=maybe-uninitialized] 343 | if (iter->_next->next == iter->_head) | ^ src/nm-ip6-config.c:1622:33: note: 'iter._head' was declared here 1622 | NMDedupMultiIter iter; | ^ and more.
* all: update deprecated SPDX license identifiersThomas Haller2021-01-051-1/+1
| | | | | | | | | | | | | | | | These SPDX license identifiers are deprecated ([1]). Update them. [1] https://spdx.org/licenses/ sed \ -e '1 s%^/\* SPDX-License-Identifier: \(GPL-2.0\|LGPL-2.1\)+ \*/$%/* SPDX-License-Identifier: \1-or-later */%' \ -e '1,2 s%^\(--\|#\|//\) SPDX-License-Identifier: \(GPL-2.0\|LGPL-2.1\)+$%\1 SPDX-License-Identifier: \2-or-later%' \ -i \ $(git grep -l SPDX-License-Identifier -- \ ':(exclude)shared/c-*/' \ ':(exclude)shared/n-*/' \ ':(exclude)shared/systemd/src' \ ':(exclude)src/systemd/src')
* all: drop unnecessary cast for return value of g_object_new()Thomas Haller2020-11-121-6/+6
| | | | | | | | | | | | | | | C casts unconditionally force the type, and as such they don't necessarily improve type safety, but rather overcome restrictions from the compiler when necessary. Casting a void pointer is unnecessary (in C), it does not make the code more readable nor more safe. In particular for g_object_new(), which is known to return a void pointer of the right type. Drop such casts. sed 's/([A-Za-z_0-9]\+ *\* *) *g_object_new/g_object_new/g' $(git grep -l g_object_new) -i ./contrib/scripts/nm-code-format-container.sh
* core: add never-default field to NMIP{4,6}ConfigBeniamino Galvani2020-10-091-0/+21
|
* all: unify comment style for SPDX-License-Identifier tagThomas Haller2020-09-291-1/+1
| | | | | | | | | | Our coding style recommends C style comments (/* */) instead of C++ (//). Also, systemd (which we partly fork) uses C style comments for the SPDX-License-Identifier. Unify the style. $ sed -i '1 s#// SPDX-License-Identifier: \([^ ]\+\)$#/* SPDX-License-Identifier: \1 */#' -- $(git ls-files -- '*.[hc]' '*.[hc]pp')
* format: replace tabs for indentation in code commentsac/clang-formatThomas Haller2020-09-281-11/+11
| | | | | | | | | | | | sed -i \ -e 's/^'$'\t'' \*/ */g' \ -e 's/^'$'\t\t'' \*/ */g' \ -e 's/^'$'\t\t\t'' \*/ */g' \ -e 's/^'$'\t\t\t\t'' \*/ */g' \ -e 's/^'$'\t\t\t\t\t'' \*/ */g' \ -e 's/^'$'\t\t\t\t\t\t'' \*/ */g' \ -e 's/^'$'\t\t\t\t\t\t\t'' \*/ */g' \ $(git ls-files -- '*.[hc]')
* all: reformat all with new clang-format styleAntonio Cardace2020-09-281-2032/+2023
| | | | | | | | | | | | Run: ./contrib/scripts/nm-code-format.sh -i ./contrib/scripts/nm-code-format.sh -i Yes, it needs to run twice because the first run doesn't yet produce the final result. Signed-off-by: Antonio Cardace <acardace@redhat.com>
* core: use nm_platform_ip6_address_match() in nm_ip6_config_find_first_address()Thomas Haller2020-09-111-23/+2
|
* core: add NMIPConfig as base class for NMIP[46]ConfigThomas Haller2020-08-051-6/+10
| | | | | | | | | NMIP[46]Config will become much simpler than it is today. It's sole responsibility will be to expose current settings on D-Bus, in it's function as a NMDBusObject subtype. However, it still make sense to let them share a common base class. Add it.
* core: merge IPv4/IPv6 implementations of ↵Thomas Haller2020-08-051-8/+10
| | | | nm_utils_ip_{addresses,routes}_to_dbus()
* core: extract helper functions for creating address/route variant for D-BusThomas Haller2020-08-051-128/+21
| | | | | | This code will change, but in essence we will still need such a function to convert a list of addresses/routes to D-Bus. Extract the code, so it can be better reused and adjusted.
* core: inline _add_local_route_from_addr[46] helper functionThomas Haller2020-07-311-43/+29
| | | | | | | | | | In this case, the functions are only called once. Having a helper function that has no clear, unique purpose does not necessarily make the code simpler. Also, NMIP[46]Config is going to change completely. It will thereby move this code (and change it). Doing that is simpler, if we see all the relevant parts in one place.
* core: add nm_platform_dedup_multi_iter_next_*() helpers to "nmp-object.h"Thomas Haller2020-07-241-4/+4
| | | | | | This code is not specific to "nm-ip4-config.h"/"nm-ip6-config.h". It applies to everybody who wants to iterate over a dedup-multi-index of certain NMPObjects. Move it.
* core: use nm_platform_ip[46]_address_pretty_sort_cmp() in "nm-ip[46]-config.c"Thomas Haller2020-07-241-97/+6
|
* platform: add nm_platform_ip[46]_address_pretty_sort_cmp()Thomas Haller2020-07-241-0/+8
| | | | | This is the code from _addresses_sort_cmp() in "nm-ip[46]-config.h" and will replace it soon.
* core: read "disable_ipv6" sysctl before nm_ip6_config_create_setting()Thomas Haller2020-07-241-21/+2
| | | | | | | | | | | | | | First of all, the entire nm_device_generate_connection() and nm_ip._config_create_setting() approach is fundamentally flawed. You cannot generate sensible configuration by reading IP addresses from an interface. Anyway, that's what we still sometimes do, and we possibly should do it less and less. It's ugly that nm_ip6_config_capture() would read the "disable_ipv6" sysctl value and cache it in NMIP6Config. Only so that it can be use much later during nm_ip6_config_create_setting(). Instead, read the sysctl value shortly before it's needed.
* core: move _nm_ip_config_merge_route_attributes() to "NetworkManagerUtils.c"Thomas Haller2020-07-231-4/+4
| | | | | | and rename to nm_utils_ip_route_attribute_to_platform(). The function is independent from NMIP4Config. We also will use it outside of NMIP4Config. Also, "NetworkManagerUtils.c" already has similar functions that parse libnm structures to internal structures.
* core: use nmp_object_ref_set() instead of _nm_ip_config_best_default_route_set()Thomas Haller2020-07-231-7/+7
| | | | | | | | _nm_ip_config_best_default_route_set() doesn't really do anything special. Use the generic helper function for the same job. Also because NMIP4Config in the current form will be replaced by something else, and this code needs to change.
* core: only expose "type unicast" routes on D-BusThomas Haller2020-07-211-0/+3
| | | | | | | | | Currently, we would not mark non-unicast routes with their type, so they would wrongly appear as unicast routes in the D-Bus API. That is wrong. For now, just hide them. Fixes: 5d0d13f57010 ('platform: add support for local routes')
* core: fix generation of dependent local routes for VRFsac/vrf_local_route_fixAntonio Cardace2020-07-151-6/+11
| | | | | | | | | | When using VRF devices we must pre-generate dependent local routes in the VRF's table otherwise they will be incorrectly added to the local table instead. https://bugzilla.redhat.com/show_bug.cgi?id=1857133 Fixes: a199cd2a7d92 ('core: add dependent local routes configured by kernel')
* core: add dependent local routes configured by kernelAntonio Cardace2020-07-091-0/+22
| | | | | | | | | | | | | Pre-generate routes in the local table that are configured by kernel when an ip-address is assigned to an interface. This helps NM taking into account routes that are not to be deleted when a connection is reapplied (or deactivated) on an interface instead of only ignoring (when pruning) IPv6 routes having metric 0 and routes belonging to the local table having 'kernel' as proto. https://bugzilla.redhat.com/show_bug.cgi?id=1821787 (cherry picked from commit 3e5fc04df320486b0f395fe6898c86f4c0144e05)
* core: add dependent multicast route configured by kernel for IPv6Antonio Cardace2020-07-091-0/+21
| | | | | | | | | | | Pre-generate the device multicast route in the local table that are configured by kernel when an ipv6-address is assigned to an interface. This helps NM taking into account routes that are not to be deleted when a connection is reapplied on an interface. https://bugzilla.redhat.com/show_bug.cgi?id=1821787 (cherry picked from commit cd89026c5f4fa29c7bf46edb5b610ec37c18be78)
* core: fix treating route metric zero of IPv6 routes specialThomas Haller2020-07-071-9/+13
| | | | | | | | | | | | | | | | | | Userspace cannot add IPv6 routes with metric 0. Trying to do that, will be coerced by kernel to route metric 1024. For IPv4 this is different, and metric zero is commonly allowed. However, kernel itself can add IPv6 routes with metric zero: # ip -6 route show table local local fe80::2029:c7ff:fec9:698a dev v proto kernel metric 0 pref medium That means, we must not treat route metric zero special for most cases. Only, when we want to add routes (based on user configuration), we must coerce a route metric of zero to 1024. https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/563 (cherry picked from commit 1b408e243d648973b0c1116bca3bbf9fa1bd308c)
* wireguard: don't let explicit gateway override WireGuard's peer routeThomas Haller2020-04-221-1/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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)
* core: add NMIPConfigFlags for NMIPConfig flagsThomas Haller2020-04-221-0/+23
| | | | | | | | | This will be useful to set future options on the NMIPConfig. Yes, the code duplication of NMIP[46]Config is horrible. Needs to be unified in the future. (cherry picked from commit e8b86f8445cd621c21ccf87833f4c49c74c325d9)
* all: use _nm_utils_inet4_ntop() instead of nm_utils_inet4_ntop()Thomas Haller2020-01-281-7/+7
| | | | | | | | | | | | | | | | | | | | | | | | and _nm_utils_inet6_ntop() instead of nm_utils_inet6_ntop(). nm_utils_inet4_ntop()/nm_utils_inet6_ntop() are public API of libnm. For one, that means they are only available in code that links with libnm/libnm-core. But such basic helpers should be available everywhere. Also, they accept NULL as destination buffers. We keep that behavior for potential libnm users, but internally we never want to use the static buffers. This patch needs to take care that there are no callers of _nm_utils_inet[46]_ntop() that pass NULL buffers. Also, _nm_utils_inet[46]_ntop() are inline functions and the compiler can get rid of them. We should consistently use the same variant of the helper. The only downside is that the "good" name is already taken. The leading underscore is rather ugly and inconsistent. Also, with our internal variants we can use "static array indices in function parameter declarations" next. Thereby the compiler helps to ensure that the provided buffers are of the right size.
* core: don't add prefix route for external addressesBeniamino Galvani2019-10-231-0/+2
| | | | | | | | | | | | | | | If the user adds an address manually, kernel automatically adds a prefix route for it unless the address has the NOPREFIXROUTE flag. When ip_config_merge_and_apply() gets called, NM also adds its prefix route and so we end up with two routes that differ only for the metric. This is a problem because the route added by NM is not removed if the user removes the previously added address. Also, it seems confusing to have multiple instances of the same routes. This commit skips the addition of a prefix route for addresses added manually outside of NetworkManager.
* core: track whether IP addresses are externalBeniamino Galvani2019-10-231-2/+11
| | | | | | Track whether IP addresses were added by NM or externally. In this way it becomes possible in a later commit to add prefix route only for addresses added by NM.
* all: manually drop code comments with file descriptionThomas Haller2019-10-011-2/+1
|
* all: SPDX header conversionLubomir Rintel2019-09-101-14/+1
| | | | | $ find * -type f |xargs perl contrib/scripts/spdx.pl $ git rm contrib/scripts/spdx.pl
* all: allow configuring default-routes as manual, static routesThomas Haller2019-08-131-2/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Up until now, a default-route (with prefix length zero) could not be configured directly. The user could only set ipv4.gateway, ipv4.never-default, ipv4.route-metric and ipv4.route-table to influence the setting of the default-route (respectively for IPv6). That is a problematic limitation. For one, whether a route has prefix length zero or non-zero does not make a fundamental difference. Also, it makes it impossible to configure all the routing attributes that one can configure otherwise for static routes. For example, the default-route could not be configured as "onlink", could not have a special MTU, nor could it be placed in a dedicated routing table. Fix that by lifting the restriction. Note that "ipv4.never-default" does not apply to /0 manual routes. Likewise, the previous manners of configuring default-routes ("ipv4.gateway") don't conflict with manual default-routes. Server-side this all the pieces are already in place to accept a default-route as static routes. This was done by earlier commits like 5c299454b49b ('core: rework tracking of gateway/default-route in ip-config'). A long time ago, NMIPRoute would assert that the prefix length is positive. That was relaxed by commit a2e93f2de4ac ('libnm: allow zero prefix length for NMIPRoute'), already before 1.0.0. Using libnm from before 1.0.0 would result in assertion failures. Note that the default-route-metric-penalty based on connectivity checking applies to all /0 routes, even these static routes. Be they added due to DHCP, "ipv4.gateway", "ipv4.routes" or "wireguard.peer-routes". I wonder whether doing that unconditionally is desirable, and maybe there should be a way to opt-out/opt-in for the entire profile or even per-routes. https://bugzilla.redhat.com/show_bug.cgi?id=1714438
* core: assert for valid arguments in _addresses_sort_cmp()Thomas Haller2019-08-021-0/+3
| | | | | | | Coverity thinks that the arguments could be %NULL. Add an assertion, hoping to silence coverity. (cherry picked from commit 1b30797bc16c7e0cc2e6c5686e52aa12ef5a5425)
* core: fix mangling static IPv6 routes in nm_ip6_config_merge_setting()Thomas Haller2019-07-091-1/+1
| | | | | | https://bugzilla.redhat.com/show_bug.cgi?id=1727193 Fixes: 433d2f8659e3 ('core: merge IPv4 and IPv6 version of _nm_ip_config_merge_route_attributes()')
* core: support creating ip6-config setting with disabled methodBeniamino Galvani2019-06-111-2/+28
| | | | | Create the new setting with method=disabled if IPv6 is disabled in the sysctl.
* all: drop emacs file variables from source filesThomas Haller2019-06-111-1/+0
| | | | | | | | | | | | | | | | | | | | | | We no longer add these. If you use Emacs, configure it yourself. Also, due to our "smart-tab" usage the editor anyway does a subpar job handling our tabs. However, on the upside every user can choose whatever tab-width he/she prefers. If "smart-tabs" are used properly (like we do), every tab-width will work. No manual changes, just ran commands: F=($(git grep -l -e '-\*-')) sed '1 { /\/\* *-\*- *[mM]ode.*\*\/$/d }' -i "${F[@]}" sed '1,4 { /^\(#\|--\|dnl\) *-\*- [mM]ode/d }' -i "${F[@]}" Check remaining lines with: git grep -e '-\*-' The ultimate purpose of this is to cleanup our files and eventually use SPDX license identifiers. For that, first get rid of the boilerplate lines.
* shared: move most of "shared/nm-utils" to "shared/nm-glib-aux"Thomas Haller2019-04-181-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | From the files under "shared/nm-utils" we build an internal library that provides glib-based helper utilities. Move the files of that basic library to a new subdirectory "shared/nm-glib-aux" and rename the helper library "libnm-core-base.la" to "libnm-glib-aux.la". Reasons: - the name "utils" is overused in our code-base. Everything's an "utils". Give this thing a more distinct name. - there were additional files under "shared/nm-utils", which are not part of this internal library "libnm-utils-base.la". All the files that are part of this library should be together in the same directory, but files that are not, should not be there. - the new name should better convey what this library is and what is isn't: it's a set of utilities and helper functions that extend glib with funcitonality that we commonly need. There are still some files left under "shared/nm-utils". They have less a unifying propose to be in their own directory, so I leave them there for now. But at least they are separate from "shared/nm-glib-aux", which has a very clear purpose. (cherry picked from commit 80db06f768e47541eae7d66ef48fbe47bf1a69ce)
* core: allow ignoring addresses when intersecting ip configsBeniamino Galvani2019-03-111-21/+42
| | | | | | | | Add a new argument to nm_ip_config_* helpers to also ignore addresses similarly to what we already do for routes. This will be used in the next commit; no change in behavior here. (cherry picked from commit 39b72572087a1243725a48d47d53131591417aec)
* nm: Fix syntax on introspection annotationsMarco Trevisan (Treviño)2019-03-071-1/+1
| | | | | | | | Various annotations were added using multiple colons, while only one has to be added or g-ir-introspect will consider them part of the description https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/94 (cherry picked from commit 73005fcf5b957a4cf7f8244da85ade0214db7606)
* all: drop unnecessary includes of <errno.h> and <string.h>Thomas Haller2019-02-121-1/+0
| | | | | "nm-macros-interal.h" already includes <errno.h> and <string.h>. No need to include it everywhere else too.
* all: don't use "static inline" in source filesThomas Haller2019-02-061-2/+2
| | | | | | | | For static functions inside a module, the compiler determines on its own whether to inline the function. Also, "inline" was used at some places that don't immediatly look like candidates for inlining. It was most likely a copy&paste error.
* core: allow addresses with zero prefix lengthThomas Haller2018-12-191-1/+3
| | | | | | | | | | | | | There is really no problem here, allow it. Previously we would assert against a non-zero prefix length. But I am not sure that all callers really ensured that this couldn't happen. Anyway, there is no problem we such addresses, really. Only we need to make sure that nm_ip4_config_add_dependent_routes() and nm_ip6_config_add_dependent_routes() don't add prefix routes for such addresses (which is the case now).
* all: don't use static buffer for nm_utils_inet*_ntop()Thomas Haller2018-12-191-9/+10
| | | | | | | | | | While nm_utils_inet*_ntop() accepts a %NULL buffer to fallback to a static buffer, don't do that. I find the possibility of using a static buffer here error prone and something that should be avoided. There is of course the downside, that in some cases it requires an additional line of code to allocate the buffer on the stack as auto-variable.
* all: cleanup GChecksum handlingThomas Haller2018-11-131-17/+7
| | | | | | | - prefer nm_auto_free_checksum over explicit free. - use nm_utils_checksum_get_digest*(). - prefer defines for digest length. - assume g_checksum_new() cannot fail.
* ip-config: add @intersect_routes argument to intersect functionsBeniamino Galvani2018-09-261-2/+11
| | | | | In some cases we want to intersect two IP configurations without considering routes.
* core: improve nm_ip_config_dump()Beniamino Galvani2018-09-261-47/+0
| | | | | | | | | Previously we had nm_ip{4,6}_config_dump() for debugging purposes, but they were inconveniently printing to stdout and so the output was not ordered in the journal. Implement a unified nm_ip_config_dump() that logs through the usual logging mechanism.
* core: handle route metric when reapplying dynamic IP methodsBeniamino Galvani2018-08-081-0/+31
| | | | | | | | | | For dynamic IP methods (DHCP, IPv4LL, WWAN) the route metric is set at activation/renewal time using the value from static configuration. To support runtime change we need to update the dynamic configuration in place and tell the DHCP client the new value to use for future renewals. https://bugzilla.redhat.com/show_bug.cgi?id=1528071
* core: use nm_gobject_notify_together() in NMIP4Config/NMIP6ConfigThomas Haller2018-08-011-4/+4
| | | | | | | | | | | | | | | | | | | | | | 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.