Connection defaults should correspond in range to the per-profile values.
"infiniband.mtu" is required to be not larger than 65520, so we also
need to honor that when parsing the connection default.
This is wrong -- we may want to start activating before device is
registered if it the SIM needs unlocking with a PIN code that's included
in the connection.
This reverts commit 2e8f43e379.
Based on Ubuntu's "Modify NMDeviceModem's available logic" patch by
Tony Espy <espy@canonical.com>. The original commit message:
This patch modifies NMDeviceModem's available logic such that the device
is only considered available if the modem_state is
>= NM_MODEM_STATE_REGISTERED. NMDevice defines 'available' as meaning the
device is in such a state that it can be activated. This change prevents
NM from trying to activate a modem which is not yet ready to be activated.
Bug-Ubuntu: https://bugs.launchpad.net/bugs/1445080https://github.com/NetworkManager/NetworkManager/pull/312
dev2_ip_config (formerly wwan_ip_config) is only set by nm_device_set_dev2_ip_config()
(formerly nm_device_set_wwan_ip_config()), which is only called by NMDeviceModem.
For NMDeviceWireGuard we will also inject additional configuration
in the parent class. Rename and give it a wider purpose. The new name
merely indicates that this IP configuration is injected by a subclass
of NMDevice.
It is preferable to treat IPv4 and IPv6 in a similar manner.
This moves the places where we differ down the call-stack.
It also make it clearer how IPv6 behaves differently. I think this
is a bug, but leave it for now.
+ /* If IP had previously failed, move it back to IP_CONF since we
+ * clearly now have configuration.
+ */
+ if (priv->ip6_state == IP_FAIL)
+ _set_ip_state (self, AF_INET6, IP_CONF);
These functions call platform's sysctl getter and setters.
Note that the called platform functions are called nm_platform_sysctl_get()
and nm_platform_sysctl_set(). Also, in this case they use the ip-conf path
via nm_utils_sysctl_ip_conf_path().
Also, next we will add API nm_platform_sysctl_ip_conf_get() and
nm_platform_sysctl_ip_conf_set(), which will be wrappers around
nm_platform_sysctl_get() and nm_platform_sysctl_set(), using the ip-conf
paths as well.
Rename the device functions, to be more similar to the existing and future
naming in platform.
For one, next we will drop setting rp_filter, hence there are no
more users of an IPv4 variant and nm_device_ipv4_sysctl_set() would
have to be dropped anyway.
However, instead of doing that, merge the IPv4 and IPv6 variant.
With this, the fallback to the default is now also supported for IPv6
(though unused).
Also, don't access nm_device_get_ip_iface(). The interface name might
not be right, we should only rely on the ifindex. Load the interface
name from platform cache instead.
The 'number' property in GSM settings is a legacy thing that comes
from when ModemManager used user-provided numbers, if any, to connect
3GPP modems.
Since ModemManager 1.0, this property is completely unused for 3GPP
modems, and so it doesn't make sense to use it in the NetworkManager
settings. Ofono does not use it either.
For AT+PPP-based 3GPP modems, the 'number' to call to establish the
data connection is decided by ModemManager itself, e.g. for standard
GSM/UMTS/LTE modems it will connect a given predefined PDP context,
and for other modems like Iridium it will have the number to call
hardcoded in the plugin itself.
https://github.com/NetworkManager/NetworkManager/pull/261
The reasons to block autoconnection at settings level are not the same
as the ones to block autoconnection at device level.
E.g. if the SIM-PIN is wrong, you may want to block autoconnection
both at settings level (as the PIN configured in settings is wrong)
and at device level (so that no other setting is tried automatically).
For some other reasons, you may want to block autoconnection only at
setting level (e.g. wrong APN).
And for some other reasons you may want to block autoconnection at
device level only (e.g. SIM missing), so that the autoconnection
blocking is removed when the device goes away. This is especially
important with SIM hotplug events processed by ModemManager, as a
device without SIM will be removed from MM when a new SIM is
inserted, so that a completely new object is exposed in MM with the
newly detected SIM.
https://github.com/NetworkManager/NetworkManager/pull/259
Refactor some code to use nm_streq() and NM_IN_STRSET() instead of
strcmp().
Note that nm_utils_get_ip_config_method() never returns %NULL (not even
with g_return*() assertion failures). nm_streq() is sufficent.
Recently, more and more code was refactored to use an addr_family
integer to distinguish between IPv4 and IPv6.
Refactor nm_utils_get_ip_config_method() and nm_device_get_effective_ip_config_method()
to do that too. If we use different identifiers, we need to translate from one to
another and its inconsistent. Also, accessing a GType is an unnecessary function call,
instead of a plain constant.
- fix stopping ppp-manager. Previously, we would take a reference
to priv->ppp_manager to cancel it later. However, deactivate_cleanup()
is called first, which already issues nm_ppp_manager_stop().
Thereby, not using a callback and not waiting for the operation
to complete.
- get rid of this "step" state machine. There are litterally two steps
that need to be performed asynchornously. Instead chain the calls.
- it is now obviously visible, that the async callback never completes
synchronously upon being called (provided that all async operations
that it calls themself have this behavior -- which they should).
Previously nm_ppp_manager_stop() would return a handle which
makes it easy to cancel the operation.
However, sometimes, we may want to cancel an operation based on
an GCancellable. So, extend nm_ppp_manager_stop() to hook it
with a cancellable.
Essentially, move the code from nm-modem.c to nm-ppp-manager-call.c,
where it belongs and where the functionality gets available to every
component.
We should not use GAsyncResult. At least, not for internal API.
It's more cumbersome then helpful, in my opinion. It requires
this awkward async_finish() pattern.
Instead, let the caller pass a suitable callback of the right type.
As we accept addr_family %AF_UNSPEC to detect the address family,
we also need to return it. Just returning the binary address without
the address family makes no sense.
Note the special error codes NM_UTILS_ERROR_CONNECTION_AVAILABLE_*.
This will be used to determine, whether the profile is fundamentally
incompatible with the device, or whether just some other properties
mismatch. That information will be importand during a plain `nmcli
connection up`, where NetworkManager searches all devices for a device
to activate. If no device is found (and multiple errors happened),
we want to show the error that is most likely relevant for the user.
Also note, how NMDevice's check_connection_compatible() uses the new
class field "device_class->connection_type_check_compatible" to simplify
checks for compatible profiles.
The error reason is still unused.
We also have NMDeviceClass.check_connection_compatible(). It is preferable
to use unique names, especially for the virtual function table. A reasonable
thing to do is grep for the function name to find all places that implement
this function. But if different classes use the same name, grep just
turns up annoying false positives.
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[@]}"
Instead of returning a boolean @is_user_config value from
get_configured_mtu(), return an mtu-source enum with possible values
NONE,CONNECTION. This enum will be expanded later; for now there is no
change in behavior.
We set the metric to the routes as we receive them from the PPP plugin. We
ought to let the modem know before it starts IPv4 configuration, not right
before the commit.
https://bugzilla.redhat.com/show_bug.cgi?id=1585611
Previously, there were two functions nm_ppp_manager_stop_sync() and
nm_ppp_manager_stop_async().
However, stop-sync() would still kill the process asynchronously (with a
2 seconds timeout before sending SIGKILL).
On the other hand, stop-async() did pretty much the same thing as
sync-code, except also using the GAsyncResult.
Merge the two functions. Stopping the instance for the most part can be
done entirely synchrnous. The only thing that is asynchronous, is
to wait for the process to terminate. For that, add a new callback
argument to nm_ppp_manager_stop(). This replaces the GAsyncResult
pattern.
Also, always ensure that NetworkManager runs the mainloop at least as
long until the process really terminated. Currently we don't get that
right, and during shutdown we just stop iterating the mainloop. However,
fix this from point of view of NMPPPManager and register a wait-object,
that later will correctly delay shutdown.
Also, NMDeviceWwan cared to wait (asynchronously) until pppd really
terminated. Keep that functionality. nm_ppp_manager_stop() returns
a handle that can be used to cancel the asynchrounous request and invoke
the callback right away. However note, that even when cancelling the
request, the wait-object that prevents shutdown of NetworkManager is
kept around, so that we can be sure to properly clean up.
Coccinelle:
@@
expression a, b;
@@
-a ? a : b
+a ?: b
Applied with:
spatch --sp-file ternary.cocci --in-place --smpl-spacing --dir .
With some manual adjustments on spots that Cocci didn't catch for
reasons unknown.
Thanks to the marvelous effort of the GNU compiler developer we can now
spare a couple of bits that could be used for more important things,
like this commit message. Standards commitees yet have to catch up.
NMSettings exposes a cached list of all connection. We don't need
to clone it. Note that this is not save against concurrent modification,
meaning, add/remove of connections in NMSettings will invalidate the
list.
However, it wasn't save against that previously either, because
altough we cloned the container (GSList), we didn't take an additional
reference to the elements.
This is purely a performance optimization, we don't need to clone the
list. Also, since the original list is of type "NMConnection *const*",
use that type insistently, instead of dependent API requiring GSList.
IMO, GSList is anyway not a very nice API for many use cases because
it requires an additional slice allocation for each element. It's
slower, and often less convenient to use.
nm_modem_complete_connection() cannot just return FALSE in case
the modem doesn't overwrite complete_connection(). It must set
the error variable.
This leads to a crash when calling AddAndActivate for Ofono type
modem. It does not affect the ModemManager implementation
NMModemBroadband, because that one implements the method.
The g_clear_pointer() macro already contains a cast to GDestroyNotify. No
need to do it ourself. In fact, with the cast, this only works with the
particular g_clear_pointer() implementation, that first assigns the
destroy function to a local variable.
See-also: https://bugzilla.gnome.org/show_bug.cgi?id=674634#c52
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
Depending on the bearer's configuration method, the data-port is
either a networking interface, or an tty for ppp.
Let's treat them strictily separate.
Also, rework how NM_MODEM_DATA_PORT was used in both contexts.
Instead, use the that we actually care about.
Also, when nm_device_set_ip_ifindex() fails, fail activation
right away.
Also, we early try to resolve the network interface's name to
an ifindex. If that fails, the device is already gone and we
fail early.