Commit graph

613 commits

Author SHA1 Message Date
Thomas Haller 41d81e6893 shared/logging: add "nm-logging-base.h"
We have "nm-logging-fwd.h", which (as the name implies) is header-only.
Add instead a "nm-logging-base.c", which also contains implementation for
logging functions that are not only useful under "src/nm-logging.c"
2019-11-28 19:20:33 +01:00
Thomas Haller ce0e898fb4 libnm: refactor caching of D-Bus objects in NMClient
No longer use GDBusObjectMangaerClient and gdbus-codegen generated classes
for the NMClient cache. Instead, use GDBusConnection directly and a
custom implementation (NMLDBusObject) for caching D-Bus' ObjectManager
data.

CHANGES
-------

- This is a complete rework. I think the previous implementation was
difficult to understand. There were unfixed bugs and nobody understood
the code well enough to fix them. Maybe somebody out there understood the
code, but I certainly did not. At least nobody provided patches to fix those
issues. I do believe that this implementation is more straightforward and
easier to understand. It removes a lot of layers of code. Whether this claim
of simplicity is true, each reader must decide for himself/herself. Note
that it is still fairly complex.

- There was a lingering performance issue with large number of D-Bus
objects. The patch tries hard that the implementation scales well. Of
course, when we cache N objects that have N-to-M references to other,
we still are fundamentally O(N*M) for runtime and memory consumption (with
M being the number of references between objects). But each part should behave
efficiently and well.

- Play well with GMainContext. libnm code (NMClient) is generally not
thread safe. However, it should work to use multiple instances in
parallel, as long as each access to a NMClient is through the caller's
GMainContext. This follows glib's style and effectively allows to use NMClient
in a multi threaded scenario. This implies to stick to a main context
upon construction and ensure that callbacks are only invoked when
iterating that context. Also, NMClient itself shall never iterate the
caller's context. This also means, libnm must never use g_idle_add() or
g_timeout_add(), as those enqueue sources in the g_main_context_default()
context.

- Get ordering of messages right. All events are consistently enqueued
in a GMainContext and processed strictly in order. For example,
previously "nm-object.c" tried to combine signals and emit them on an
idle handler. That is wrong, signals must be emitted in the right order
and when they happen. Note that when using GInitable's synchronous initialization
to initialize the NMClient instance, NMClient internally still operates fully
asynchronously. In that case NMClient has an internal main context.

- NMClient takes over most of the functionality. When using D-Bus'
ObjectManager interface, one needs to handle basically the entire state
of the D-Bus interface. That cannot be separated well into distinct
parts, and even if you try, you just end up having closely related code
in different source files. Spreading related code does not make it
easier to understand, on the contrary. That means, NMClient is
inherently complex as it contains most of the logic. I think that is
not avoidable, but it's not as bad as it sounds.

- NMClient processes D-Bus messages and state changes in separate steps.
First NMClient unpacks the message (e.g. _dbus_handle_properties_changed()) and
keeps track of the changed data. Then we update the GObject instances
(_dbus_handle_obj_changed_dbus()) without emitting any signals yet. Finally,
we emit all signals and notifications that were collected
(_dbus_handle_changes_commit()). Note that for example during the initial
GetManagedObjects() reply, NMClient receive a large amount of state at once.
But we first apply all the changes to our GObject instances before
emitting any signals. The result is that signals are always emitted in a moment
when the cache is consistent. The unavoidable downside is that when you receive
a property changed signal, possibly many other properties changed
already and more signals are about to be emitted.

- NMDeviceWifi no longer modifies the content of the cache from client side
during poke_wireless_devices_with_rf_status(). The content of the cache
should be determined by D-Bus alone and follow what NetworkManager
service exposes. Local modifications should be avoided.

- This aims to bring no API/ABI change, though it does of course bring
various subtle changes in behavior. Those should be all for the better, but the
goal is not to break any existing clients. This does change internal
(albeit externally visible) API, like dropping NM_OBJECT_DBUS_OBJECT_MANAGER
property and NMObject no longer implementing GInitableIface and GAsyncInitableIface.

- Some uses of gdbus-codegen classes remain in NMVpnPluginOld, NMVpnServicePlugin
and NMSecretAgentOld. These are independent of NMClient/NMObject and
should be reworked separately.

- While we no longer use generated classes from gdbus-codegen, we don't
need more glue code than before. Also before we constructed NMPropertiesInfo and
a had large amount of code to propagate properties from NMDBus* to NMObject.
That got completely reworked, but did not fundamentally change. You still need
about the same effort to create the NMLDBusMetaIface. Not using
generated bindings did not make anything worse (which tells about the
usefulness of generated code, at least in the way it was used).

- NMLDBusMetaIface and other meta data is static and immutable. This
avoids copying them around. Also, macros like NML_DBUS_META_PROPERTY_INIT_U()
have compile time checks to ensure the property types matches. It's pretty hard
to misuse them because it won't compile.

- The meta data now explicitly encodes the expected D-Bus types and
makes sure never to accept wrong data. That would only matter when the
server (accidentally or intentionally) exposes unexpected types on
D-Bus. I don't think that was previously ensured in all cases.
For example, demarshal_generic() only cared about the GObject property
type, it didn't know the expected D-Bus type.

- Previously GDBusObjectManager would sometimes emit warnings (g_log()). Those
probably indicated real bugs. In any case, it prevented us from running CI
with G_DEBUG=fatal-warnings, because there would be just too many
unrelated crashes. Now we log debug messages that can be enabled with
"LIBNM_CLIENT_DEBUG=trace". Some of these messages can also be turned
into g_warning()/g_critical() by setting LIBNM_CLIENT_DEBUG=warning,error.
Together with G_DEBUG=fatal-warnings, this turns them into assertions.
Note that such "assertion failures" might also happen because of a server
bug (or change). Thus these are not common assertions that indicate a bug
in libnm and are thus not armed unless explicitly requested. In our CI we
should now always run with LIBNM_CLIENT_DEBUG=warning,error and
G_DEBUG=fatal-warnings and to catch bugs. Note that currently
NetworkManager has bugs in this regard, so enabling this will result in
assertion failures. That should be fixed first.

- Note that this changes the order in which we emit "notify:devices" and
"device-added" signals. I think it makes the most sense to emit first
"device-removed", then "notify:devices", and finally "device-added"
signals.
This changes behavior for commit 52ae28f6e5 ('libnm: queue
added/removed signals and suppress uninitialized notifications'),
but I don't think that users should actually rely on the order. Still,
the new order makes the most sense to me.

- In NetworkManager, profiles can be invisible to the user by setting
"connection.permissions". Such profiles would be hidden by NMClient's
nm_client_get_connections() and their "connection-added"/"connection-removed"
signals.
Note that NMActiveConnection's nm_active_connection_get_connection()
and NMDevice's nm_device_get_available_connections() still exposes such
hidden NMRemoteConnection instances. This behavior was preserved.

NUMBERS
-------

I compared 3 versions of libnm.

  [1] 962297f908, current tip of nm-1-20 branch
  [2] 4fad8c7c64, current master, immediate parent of this patch
  [3] this patch

All tests were done on Fedora 31, x86_64, gcc 9.2.1-1.fc31.
The libraries were build with

  $ ./contrib/fedora/rpm/build_clean.sh -g -w test -W debug

Note that RPM build already stripped the library.

---

N1) File size of libnm.so.0.1.0 in bytes. There currently seems to be a issue
  on Fedora 31 generating wrong ELF notes. Usually, libnm is smaller but
  in these tests it had large (and bogus) ELF notes. Anyway, the point
  is to show the relative sizes, so it doesn't matter).

  [1] 4075552 (102.7%)
  [2] 3969624 (100.0%)
  [3] 3705208 ( 93.3%)

---

N2) `size /usr/lib64/libnm.so.0.1.0`:

          text             data              bss                dec               hex   filename
  [1]  1314569 (102.0%)   69980 ( 94.8%)   10632 ( 80.4%)   1395181 (101.4%)   1549ed   /usr/lib64/libnm.so.0.1.0
  [2]  1288410 (100.0%)   73796 (100.0%)   13224 (100.0%)   1375430 (100.0%)   14fcc6   /usr/lib64/libnm.so.0.1.0
  [3]  1229066 ( 95.4%)   65248 ( 88.4%)   13400 (101.3%)   1307714 ( 95.1%)   13f442   /usr/lib64/libnm.so.0.1.0

---

N3) Performance test with test-client.py. With checkout of [2], run

```
prepare_checkout() {
    rm -rf /tmp/nm-test && \
    git checkout -B test 4fad8c7c64 && \
    git clean -fdx && \
    ./autogen.sh --prefix=/tmp/nm-test && \
    make -j 5 install && \
    make -j 5 check-local-clients-tests-test-client
}
prepare_test() {
    NM_TEST_REGENERATE=1 NM_TEST_CLIENT_BUILDDIR="/data/src/NetworkManager" NM_TEST_CLIENT_NMCLI_PATH=/usr/bin/nmcli python3 ./clients/tests/test-client.py -v
}
do_test() {
  for i in {1..10}; do
      NM_TEST_CLIENT_BUILDDIR="/data/src/NetworkManager" NM_TEST_CLIENT_NMCLI_PATH=/usr/bin/nmcli python3 ./clients/tests/test-client.py -v || return -1
  done
  echo "done!"
}
prepare_checkout
prepare_test
time do_test
```

  [1]  real 2m14.497s (101.3%)     user 5m26.651s (100.3%)     sys  1m40.453s (101.4%)
  [2]  real 2m12.800s (100.0%)     user 5m25.619s (100.0%)     sys  1m39.065s (100.0%)
  [3]  real 1m54.915s ( 86.5%)     user 4m18.585s ( 79.4%)     sys  1m32.066s ( 92.9%)

---

N4) Performance. Run NetworkManager from build [2] and setup a large number
of profiles (551 profiles and 515 devices, mostly unrealized). This
setup is already at the edge of what NetworkManager currently can
handle. Of course, that is a different issue. Here we just check how
long plain `nmcli` takes on the system.

```
do_cleanup() {
    for UUID in $(nmcli -g NAME,UUID connection show | sed -n 's/^xx-c-.*:\([^:]\+\)$/\1/p'); do
        nmcli connection delete uuid "$UUID"
    done
    for DEVICE in $(nmcli -g DEVICE device status | grep '^xx-i-'); do
        nmcli device delete "$DEVICE"
    done
}

do_setup() {
    do_cleanup
    for i in {1..30}; do
        nmcli connection add type bond autoconnect no con-name xx-c-bond-$i ifname xx-i-bond-$i ipv4.method disabled ipv6.method ignore
        for j in $(seq $i 30); do
            nmcli connection add type vlan autoconnect no con-name xx-c-vlan-$i-$j vlan.id $j ifname xx-i-vlan-$i-$j vlan.parent xx-i-bond-$i  ipv4.method disabled ipv6.method ignore
        done
    done
    systemctl restart NetworkManager.service
    sleep 5
}

do_test() {
    perf stat -r 50 -B nmcli 1>/dev/null
}

do_test
```

  [1]

   Performance counter stats for 'nmcli' (50 runs):

              456.33 msec task-clock:u              #    1.093 CPUs utilized            ( +-  0.44% )
                   0      context-switches:u        #    0.000 K/sec
                   0      cpu-migrations:u          #    0.000 K/sec
               5,900      page-faults:u             #    0.013 M/sec                    ( +-  0.02% )
       1,408,675,453      cycles:u                  #    3.087 GHz                      ( +-  0.48% )
       1,594,741,060      instructions:u            #    1.13  insn per cycle           ( +-  0.02% )
         368,744,018      branches:u                #  808.061 M/sec                    ( +-  0.02% )
           4,566,058      branch-misses:u           #    1.24% of all branches          ( +-  0.76% )

             0.41761 +- 0.00282 seconds time elapsed  ( +-  0.68% )

  [2]

   Performance counter stats for 'nmcli' (50 runs):

              477.99 msec task-clock:u              #    1.088 CPUs utilized            ( +-  0.36% )
                   0      context-switches:u        #    0.000 K/sec
                   0      cpu-migrations:u          #    0.000 K/sec
               5,948      page-faults:u             #    0.012 M/sec                    ( +-  0.03% )
       1,471,133,482      cycles:u                  #    3.078 GHz                      ( +-  0.36% )
       1,655,275,369      instructions:u            #    1.13  insn per cycle           ( +-  0.02% )
         382,595,152      branches:u                #  800.433 M/sec                    ( +-  0.02% )
           4,746,070      branch-misses:u           #    1.24% of all branches          ( +-  0.49% )

             0.43923 +- 0.00242 seconds time elapsed  ( +-  0.55% )

  [3]

   Performance counter stats for 'nmcli' (50 runs):

              352.36 msec task-clock:u              #    1.027 CPUs utilized            ( +-  0.32% )
                   0      context-switches:u        #    0.000 K/sec
                   0      cpu-migrations:u          #    0.000 K/sec
               4,790      page-faults:u             #    0.014 M/sec                    ( +-  0.26% )
       1,092,341,186      cycles:u                  #    3.100 GHz                      ( +-  0.26% )
       1,209,045,283      instructions:u            #    1.11  insn per cycle           ( +-  0.02% )
         281,708,462      branches:u                #  799.499 M/sec                    ( +-  0.01% )
           3,101,031      branch-misses:u           #    1.10% of all branches          ( +-  0.61% )

             0.34296 +- 0.00120 seconds time elapsed  ( +-  0.35% )

---

N5) same setup as N4), but run `PAGER= /bin/time -v nmcli`:

  [1]

        Command being timed: "nmcli"
        User time (seconds): 0.42
        System time (seconds): 0.04
        Percent of CPU this job got: 107%
        Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.43
        Average shared text size (kbytes): 0
        Average unshared data size (kbytes): 0
        Average stack size (kbytes): 0
        Average total size (kbytes): 0
        Maximum resident set size (kbytes): 34456
        Average resident set size (kbytes): 0
        Major (requiring I/O) page faults: 0
        Minor (reclaiming a frame) page faults: 6128
        Voluntary context switches: 1298
        Involuntary context switches: 1106
        Swaps: 0
        File system inputs: 0
        File system outputs: 0
        Socket messages sent: 0
        Socket messages received: 0
        Signals delivered: 0
        Page size (bytes): 4096
        Exit status: 0

  [2]
        Command being timed: "nmcli"
        User time (seconds): 0.44
        System time (seconds): 0.04
        Percent of CPU this job got: 108%
        Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.44
        Average shared text size (kbytes): 0
        Average unshared data size (kbytes): 0
        Average stack size (kbytes): 0
        Average total size (kbytes): 0
        Maximum resident set size (kbytes): 34452
        Average resident set size (kbytes): 0
        Major (requiring I/O) page faults: 0
        Minor (reclaiming a frame) page faults: 6169
        Voluntary context switches: 1849
        Involuntary context switches: 142
        Swaps: 0
        File system inputs: 0
        File system outputs: 0
        Socket messages sent: 0
        Socket messages received: 0
        Signals delivered: 0
        Page size (bytes): 4096
        Exit status: 0

  [3]

        Command being timed: "nmcli"
        User time (seconds): 0.32
        System time (seconds): 0.02
        Percent of CPU this job got: 102%
        Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.34
        Average shared text size (kbytes): 0
        Average unshared data size (kbytes): 0
        Average stack size (kbytes): 0
        Average total size (kbytes): 0
        Maximum resident set size (kbytes): 29196
        Average resident set size (kbytes): 0
        Major (requiring I/O) page faults: 0
        Minor (reclaiming a frame) page faults: 5059
        Voluntary context switches: 919
        Involuntary context switches: 685
        Swaps: 0
        File system inputs: 0
        File system outputs: 0
        Socket messages sent: 0
        Socket messages received: 0
        Signals delivered: 0
        Page size (bytes): 4096
        Exit status: 0

---

N6) same setup as N4), but run `nmcli monitor` and look at `ps aux` for
  the RSS size.

      USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
  [1] me     1492900 21.0  0.2 461348 33248 pts/10   Sl+  15:02   0:00 nmcli monitor
  [2] me     1490721  5.0  0.2 461496 33548 pts/10   Sl+  15:00   0:00 nmcli monitor
  [3] me     1495801 16.5  0.1 459476 28692 pts/10   Sl+  15:04   0:00 nmcli monitor
2019-11-25 15:08:00 +01:00
Thomas Haller 18c5ce50fb build: create base directories for install-data-hook first
The dependencies of make are exectured in the order as they appear.
We probably should start by creating the directories, before invoking
other install hooks. Currently there is no difference, because none of
the other hooks depend on the base directories. Still split it to
a special target.
2019-11-22 15:59:31 +01:00
Thomas Haller d1eb52f8ce build: cleanup Makefile.am by moving "data_edit" first
$(data_edit) will be used later at an earlier place in the
makefile (to edit "clients/cloud-setup/nm-cloud-setup.service",
which will be handled earlier). Move it.

Also minor cleanups, like allowing to incrementally build
systemdsystemunit_DATA variable.
2019-11-22 15:59:31 +01:00
Thomas Haller c016165e1b systemd: merge branch systemd into master 2019-11-20 09:22:53 +01:00
Thomas Haller 8f37a0ae0a build: link "nm-enum-types.c" with the base "liblibnm" instead of "libnm"
This way the symbols are also available to the unit tests.
2019-10-18 22:09:18 +02:00
Lubomir Rintel 7061341a41 cli: add "nmcli d wifi show"
A quick overview of the currently connected Wi-Fi network, including
credentials. Comes handy if someone wants to connect more devices to
their Hotspot or the same network as they are connected to.
2019-10-18 17:38:57 +02:00
Iñigo Martínez 42a8533d5f meson: Remove devices tests' meson build files
The devices tests' meson build files include only the build of a
single executable file and its execution as a test unit.

This has been moved to the devices' main meson build files so this
files can be removed.
2019-10-01 09:49:33 +02:00
Iñigo Martínez 05c7a77022 meson: Add missing "nm-bt-test" helper program
In 878d4963e a new `nm-bt-test` helper program was added. However,
although `autotools` build steps were included, meson build steps
were not.

This add meson's build steps.
2019-10-01 09:49:33 +02:00
Beniamino Galvani a79572c261 build: avoid target redefinition
Makefile.am:3462: warning: $(src_devices_bluetooth_libnm_device_plugin_bluetooth_la_OBJECTS) was already defined in condition TRUE, which includes condition WITH_MODEM_MANAGER_1 ...
 Makefile.am:960: ... '$(src_devices_bluetooth_libnm_device_plugin_bluetooth_la_OBJECTS)' previously defined here

Fixes: 878d4963ed ('bluetooth/tests: add "nm-bt-test helper" program for manual testing of bluetooth code')
2019-09-24 15:39:26 +02:00
Thomas Haller 4154d9618c bluetooth: refactor BlueZ handling and let NMBluezManager cache ObjectManager data
This is a complete refactoring of the bluetooth code.

Now that BlueZ 4 support was dropped, the separation of NMBluezManager
and NMBluez5Manager makes no sense. They should be merged.

At that point, notice that BlueZ 5's D-Bus API is fully centered around
D-Bus's ObjectManager interface. Using that interface, we basically only
call GetManagedObjects() once and register to InterfacesAdded,
InterfacesRemoved and PropertiesChanged signals. There is no need to
fetch individual properties ever.

Note how NMBluezDevice used to query the D-Bus properties itself by
creating a GDBusProxy. This is redundant, because when using the ObjectManager
interfaces, we have all information already.

Instead, let NMBluezManager basically become the client-side cache of
all of BlueZ's ObjectManager interface. NMBluezDevice was mostly concerned
about caching the D-Bus interface's state, tracking suitable profiles
(pan_connection), and moderate between bluez and NMDeviceBt.
These tasks don't get simpler by moving them to a seprate file. Let them
also be handled by NMBluezManager.

I mean, just look how it was previously: NMBluez5Manager registers to
ObjectManager interface and sees a device appearing. It creates a
NMBluezDevice object and registers to its "initialized" and
"notify:usable" signal. In the meantime, NMBluezDevice fetches the
relevant information from D-Bus (although it was already present in the
data provided by the ObjectManager) and eventually emits these usable
and initialized signals.
Then, NMBlue5Manager emits a "bdaddr-added" signal, for which NMBluezManager
creates the NMDeviceBt instance. NMBluezManager, NMBluez5Manager and
NMBluezDevice are strongly cooperating to the point that it is simpler
to merge them.

This is not mere refactoring. This patch aims to make everything
asynchronously and always cancellable. Also, it aims to fix races
and inconsistencies of the state.

- Registering to a NAP server now waits for the response and delays
  activation of the NMDeviceBridge accordingly.

- For NAP connections we now watch the bnep0 interface in platform, and tear
  down the device when it goes away. Bluez doesn't send us a notification
  on D-Bus in that case.

- Rework establishing a DUN connection. It no longer uses blocking
  connect() and does not block until rfcomm device appears. It's
  all async now. It also watches the rfcomm file descriptor for
  POLLERR/POLLHUP to notice disconnect.

- drop nm_device_factory_emit_component_added() and instead let
  NMDeviceBt directly register to the WWan factory's "added" signal.
2019-09-23 12:47:37 +02:00
Thomas Haller 878d4963ed bluetooth/tests: add "nm-bt-test helper" program for manual testing of bluetooth code
Just add a stub implementation and let it build. More will be added
later.
2019-09-22 16:05:50 +02:00
Thomas Haller 908fadec96 shared: add NMRefString
I'd like to refactor libnm's caching. Note that cached D-Bus objects
have repeated strings all over the place. For example every object will
have a set of D-Bus interfaces (strings) and properties (strings) and an
object path (which is referenced by other objects). We can save a lot of
redundant strings by deduplicating/interning them. Also, by interning
them, we can compare them using pointer equality.

Add a NMRefString implementation for this.

Maybe an alternative name would be NMInternedString or NMDedupString, because
this string gets always interned. There is no way to create a NMRefString
that is not interned. Still, NMRefString name sounds better. It is ref-counted
after all.

Notes:

 - glib has GQuark and g_intern_string(). However, such strings cannot
   be unrefered and are leaked indefinitely. It is thus unsuited for
   anything but a fixed set of well-known strings.

 - glib 2.58 adds GRefString, but we cannot use that because we
   currently still use glib 2.40.
   There are some differences:

     - GRefString is just a typedef to char. That means, the glib API
       exposes GRefString like regular character strings.
       NMRefString intentionally does that not. This makes it slightly
       less convenient to pass it to API that expects "const char *".
       But it makes it clear to the reader, that an instance is in fact
       a NMRefString, which means it indicates that the string is
       interned and can be referenced without additional copy.

     - GRefString can be optionally interned. That means you can
       only use pointer equality for comparing values if you know
       that the GRefString was created with g_ref_string_new_intern().
       So, GRefString looks like a "const char *" pointer and even if
       you know it's a GRefString, you might not know whether it is
       interned. NMRefString is always interned, and you can always
       compare it using pointer equality.

  - In the past I already proposed a different implementation for a
    ref-string. That made different choices. For example NMRefString
    then was a typedef to "const char *", it did not support interning
    but deduplication (without a global cache), ref/unref was not
    thread safe (but then there was no global cache so that two threads
    could still use the API independently).

The point is, there are various choices to make. GRefString, the
previous NMRefString implementation and the one here, all have pros and
cons. I think for the purpose where I intend NMRefString (dedup and
efficient comparison), it is a preferable implementation.

Ah, and of course NMRefString is an immutable string, which is a nice
property.
2019-09-21 14:58:26 +02:00
Francesco Giudici 15035e2b0d meson: fix build_clean.sh -w meson -w test
Fixes: 6e5385a4eb ('wwan/tests: test service-providers.xml parser')
2019-09-13 12:59:03 +02:00
Lubomir Rintel 4af856a71b build: make test-service-providers depend on nm-core-enum-types.h
Fixes build:

  In file included from ../src/devices/wwan/nm-service-providers.c:10:
  In file included from ../shared/nm-default.h:279:
  ../libnm-core/nm-core-types.h:14:10: fatal error: 'nm-core-enum-types.h' file not found
  #include "nm-core-enum-types.h"
           ^
  1 error generated.
  make[2]: *** [src/devices/wwan/src_devices_wwan_tests_test_service_providers-nm-service-providers.o] Error 1
2019-09-11 16:42:59 +02:00
Lubomir Rintel 6e5385a4eb wwan/tests: test service-providers.xml parser
Just a handful of unit tests.
2019-09-11 14:32:05 +02:00
Lubomir Rintel 6632c77094 wwan: add service-providers.xml parser
This allows up to look up a default APN if the user doesn't pick one.
2019-09-11 14:32:05 +02:00
Lubomir Rintel 986947dbf5 initrd: fix dt test 2019-09-10 14:11:16 +02:00
Lubomir Rintel e9f2ea6c22 COPYING: make sure we ship the relevant license texts
This adds LGPL and GFDL texts from the GNU web site and updates the GPL
one:

  COPYING: https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
  COPYING.LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt
  COPYING.GFDL: https://www.gnu.org/licenses/old-licenses/fdl-1.1.txt

The update to the GPL text is purely cosmetic. However, shipping the
exact same file as GNU publishes may help distros that deduplicate the
license texts or hardlink duplicates.
2019-09-10 11:10:52 +02:00
Lubomir Rintel 7a72c705ac initrd: add devicetree support
This adds capability to hand over the network configuration from
OpenFirmware (and potentially other boot loaders with openfirmware
support such as U-Boot) to NetworkManager.

It's done analogously to ACPI/iBFT. In fact, the same ip=ibft command
line option is used, adding a more general ip=fw alias. This probably
deserves some documentation, but I'm not adding any at this time.

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/257
2019-09-10 11:04:51 +02:00
Beniamino Galvani 11cf082a62 build: use regexp in gtkdoc --ignore-decorators option
gtkdoc-scan supports regular expressions in the --ignore-decorators
command-line option. Since it is easier to use a regexp than grepping
macros from a source file, revert the ugly solution from commit
2d941dc95a ('build: fix errors when building with gtk-doc 1.32').
2019-09-06 14:18:24 +02:00
Francesco Giudici a0498e0829 meson: fix build_clean.sh -w meson -w test
Fixes: 2d941dc95a ('build: fix errors when building with gtk-doc 1.32')
2019-09-05 13:07:41 +02:00
Thomas Haller a49027ab22 ifupdown/tests: add test with duplicate interfaces
This file causes a crash [1], add it to the tests.
Note that the test only check parsing the file and the
crash happens in the "upper" layers. So, it's not really
a test for the crash. But at least have such a file in
our repository.

[1] https://gitlab.freedesktop.org/NetworkManager/NetworkManager/issues/235
2019-08-24 13:38:33 +02:00
Francesco Giudici ed5cd288c4 meson: fix build_clean.sh -w meson -w test
Fixes: 00bb6cdb4f ('build: fix meson warning about path separator in target')
2019-08-22 11:16:31 +02:00
Thomas Haller 907ea97088 bluetooth: drop BlueZ 4 support (1)
BlueZ 5.0 was released in December 2012 and broke API with
BlueZ 4. NetworkManager supports Bluez 5 for years already.

Of course, version 4 is long gone by now, so remove it.
2019-08-12 16:05:30 +02:00
Thomas Haller f6d7af9ca6 systemd: merge branch systemd into master 2019-07-26 15:00:08 +02:00
Thomas Haller d35d3c468a settings: rework tracking settings connections and settings plugins
Completely rework how settings plugin handle connections and how
NMSettings tracks the list of connections.

Previously, settings plugins would return objects of (a subtype of) type
NMSettingsConnection. The NMSettingsConnection was tightly coupled with
the settings plugin. That has a lot of downsides.

Change that. When changing this basic relation how settings connections
are tracked, everything falls appart. That's why this is a huge change.
Also, since I have to largely rewrite the settings plugins, I also
added support for multiple keyfile directories, handle in-memory
connections only by keyfile plugin and (partly) use copy-on-write NMConnection
instances. I don't want to spend effort rewriting large parts while
preserving the old way, that anyway should change. E.g. while rewriting ifcfg-rh,
I don't want to let it handle in-memory connections because that's not right
long-term.

--

If the settings plugins themself create subtypes of NMSettingsConnection
instances, then a lot of knowledge about tracking connections moves
to the plugins.
Just try to follow the code what happend during nm_settings_add_connection().
Note how the logic is spread out:
 - nm_settings_add_connection() calls plugin's add_connection()
 - add_connection() creates a NMSettingsConnection subtype
 - the plugin has to know that it's called during add-connection and
   not emit NM_SETTINGS_PLUGIN_CONNECTION_ADDED signal
 - NMSettings calls claim_connection() which hocks up the new
   NMSettingsConnection instance and configures the instance
   (like calling nm_settings_connection_added()).
This summary does not sound like a lot, but try to follow that code. The logic
is all over the place.

Instead, settings plugins should have a very simple API for adding, modifying,
deleting, loading and reloading connections. All the plugin does is to return a
NMSettingsStorage handle. The storage instance is a handle to identify a profile
in storage (e.g. a particular file). The settings plugin is free to subtype
NMSettingsStorage, but it's not necessary.
There are no more events raised, and the settings plugin implements the small
API in a straightforward manner.
NMSettings now drives all of this. Even NMSettingsConnection has now
very little concern about how it's tracked and delegates only to NMSettings.

This should make settings plugins simpler. Currently settings plugins
are so cumbersome to implement, that we avoid having them. It should not be
like that and it should be easy, beneficial and lightweight to create a new
settings plugin.

Note also how the settings plugins no longer care about duplicate UUIDs.
Duplicated UUIDs are a fact of life and NMSettings must handle them. No
need to overly concern settings plugins with that.

--

NMSettingsConnection is exposed directly on D-Bus (being a subtype of
NMDBusObject) but it was also a GObject type provided by the settings
plugin. Hence, it was not possible to migrate a profile from one plugin to
another.
However that would be useful when one profile does not support a
connection type (like ifcfg-rh not supporting VPN). Currently such
migration is not implemented except for migrating them to/from keyfile's
run directory. The problem is that migrating profiles in general is
complicated but in some cases it is important to do.

For example checkpoint rollback should recreate the profile in the right
settings plugin, not just add it to persistent storage. This is not yet
properly implemented.

--

Previously, both keyfile and ifcfg-rh plugin implemented in-memory (unsaved)
profiles, while ifupdown plugin cannot handle them. That meant duplication of code
and a ifupdown profile could not be modified or made unsaved.
This is now unified and only keyfile plugin handles in-memory profiles (bgo #744711).
Also, NMSettings is aware of such profiles and treats them specially.
In particular, NMSettings drives the migration between persistent and non-persistent
storage.

Note that a settings plugins may create truly generated, in-memory profiles.
The settings plugin is free to generate and persist the profiles in any way it
wishes. But the concept of "unsaved" profiles is now something explicitly handled
by keyfile plugin. Also, these "unsaved" keyfile profiles are persisted to file system
too, to the /run directory. This is great for two reasons: first of all, all
profiles from keyfile storage in fact have a backing file -- even the
unsaved ones. It also means you can create "unsaved" profiles in /run
and load them with `nmcli connection load`, meaning there is a file
based API for creating unsaved profiles.
The other advantage is that these profiles now survive restarting
NetworkManager. It's paramount that restarting the daemon is as
non-disruptive as possible. Persisting unsaved files to /run improves
here significantly.

--

In the past, NMSettingsConnection also implemented NMConnection interface.
That was already changed a while ago and instead users call now
nm_settings_connection_get_connection() to delegate to a
NMSimpleConnection. What however still happened was that the NMConnection
instance gets never swapped but instead the instance was modified with
nm_connection_replace_settings_from_connection(), clear-secrets, etc.
Change that and treat the NMConnection instance immutable. Instead of modifying
it, reference/clone a new instance. This changes that previously when somebody
wanted to keep a reference to an NMConnection, then the profile would be cloned.
Now, it is supposed to be safe to reference the instance directly and everybody
must ensure not to modify the instance. nmtst_connection_assert_unchanging()
should help with that.
The point is that the settings plugins may keep references to the
NMConnection instance, and so does the NMSettingsConnection. We want
to avoid cloning the instances as long as they are the same.
Likewise, the device's applied connection can now also be referenced
instead of cloning it. This is not yet done, and possibly there are
further improvements possible.

--

Also implement multiple keyfile directores /usr/lib, /etc, /run (rh #1674545,
bgo #772414).

It was always the case that multiple files could provide the same UUID
(both in case of keyfile and ifcfg-rh). For keyfile plugin, if a profile in
read-only storage in /usr/lib gets modified, then it gets actually stored in
/etc (or /run, if the profile is unsaved).

--

While at it, make /etc/network/interfaces profiles for ifupdown plugin reloadable.

--

https://bugzilla.gnome.org/show_bug.cgi?id=772414
https://bugzilla.gnome.org/show_bug.cgi?id=744711
https://bugzilla.redhat.com/show_bug.cgi?id=1674545
2019-07-16 19:09:08 +02:00
Thomas Haller ec77d477a8 build: dist test file "test-tpm2wrapped-key.pem"
Fixes: 107ba8e00c ('libnm/crypto: accept TPM2-wrapped PEM keys')
2019-07-11 09:48:56 +02:00
Beniamino Galvani deba9c4b86 build: add missing dependency for shared/systemd/src/shared
In file included from ./shared/systemd/sd-adapt-shared/nm-sd-adapt-shared.h:21,
                  from shared/systemd/src/shared/dns-domain.c:3:
 ./shared/nm-default.h:106:10: fatal error: config-extra.h: No such file or directory
  #include "config-extra.h"
          ^~~~~~~~~~~~~~~~
 compilation terminated.
 make[1]: *** [Makefile:12933: shared/systemd/src/shared/libnm_systemd_shared_la-dns-domain.lo] Error 1

Fixes: 7d3098ff90 ('systemd: add dns-domain utils to systemd static library')
2019-07-08 15:03:54 +02:00
Francesco Giudici eed205bff3 dhcp/internal: move dhcp options management to shared dhcp codebase 2019-07-05 15:13:09 +02:00
Francesco Giudici a6036b2352 dhcp: access internal systemd structure to retrieve dhcp private options 2019-07-05 14:12:21 +02:00
Beniamino Galvani 7d3098ff90 systemd: add dns-domain utils to systemd static library
dns-domain.c contains useful functions for manipulating DNS names.
Add it to the systemd static library we build in shared/, similarly to
what we already do for other utility files that were originally in
src/systemd/src/basic/.
2019-07-05 11:04:32 +02:00
Tom Gundersen 6adade6f21 dhcp: add nettools dhcp4 client
This is inspired by the existing systemd integration, with a few differences:

* This parses the WPAD option, which systemd requested, but did not use.
* We hook into the DAD handling, only making use of the configured address
  once DAD has completed successfully, and declining the lease if it fails.

There are still many areas of possible improvement. In particular, we need
to ensure the parsing of all options are compliant, as n-dhcp4 treats all
options as opaque, unlike sd-dhcp4. We probably also need to look at how
to handle failures and retries (in particular if we decline a lease).

We need to query the current MTU at client startu, as well as the hardware
broadcast address. Both these are provided by the kernel over netlink, so
it should simply be a matter of hooking that up with NM's netlink layer.

Contribution under LGPL2.0+, in addition to stated licenses.
2019-07-05 11:04:32 +02:00
Beniamino Galvani be8f7b5a5d systemd: merge branch systemd into master 2019-07-05 09:13:53 +02:00
Thomas Haller 74641be816 settings: drop ibft settings plugin
The functionality of the ibft settings plugin is now handled by
nm-initrd-generator. There is no need for it anymore, drop it.

Note that ibft called iscsiadm, which requires CAP_SYS_ADMIN to work
([1]). We really want to drop this capability, so the current solution
of a settings plugin (as it is implemented) is wrong. The solution
instead is nm-initrd-generator.

Also, on Fedora the ibft was disabled and probably on most other
distributions as well. This was only used on RHEL.

[1] https://bugzilla.redhat.com/show_bug.cgi?id=1371201#c7
2019-06-20 16:06:44 +02:00
Lubomir Rintel 11d59de600 build/autotools: generate "config-extra.h" via makefile "config-extra.h.mk"
When the code that generates "config-extra.h" changes, we want to regenerate
the file. Move that code to a separate makefile so we can add a
dependency.

Otherwise, we'd had to depend on "Makefile", which itself is generated by
Makefile.am.

Also, depend on "config.h" to regenerate it when ./configure runs and
touches that header. This may not cover all cases where ./configure's
configuration changes and a regeneration would be due. But such is life.

Also, most components depend on this header, so let various .dirstamp
files depend on it, so we are sure to build this first. That because,
autotools generates dependencies for header files automatically, but
that requires that the header file exist. Such automatic dependencies
don't work out-of-the-box for generated headers.

Co-authored-by: Thomas Haller <thaller@redhat.com>
2019-06-17 17:42:09 +02:00
Thomas Haller 721f238946 build/autotools: depend "config-extra.h" on "config.h"
"config-extra.h" is really just like "config.h", except it works around some
limitations of autoconf.

If we depend on "Makefile", any changes to "Makefile.am" will cause a full
rebuild. We want to avoid that.

Instead, depend on "config.h". That one only changes when configure runs
again. And that's the better dependancy, because "config-extra.h" is
generated based on informations generated by configure (despite being
generated by "Makefile").
2019-06-17 13:00:37 +02:00
Thomas Haller 7ed1fc817f Revert "build: only update config-extra.h if it changes"
Not touching "config-extra.h" means that the target is rebuild every
time (because the timestampt does not get updated). On the other hand,
touching it will cause a full rebuild (which we often want to avoid).

The right solution is instead to depend on "config.h", which will be
done next.

This reverts commit 14271d84a0.
2019-06-17 12:54:04 +02:00
Lubomir Rintel a26abc797c libnm-core: add ovs-dpdk setting 2019-06-14 12:10:20 +02:00
Lubomir Rintel 14271d84a0 build: only update config-extra.h if it changes
This is to avoid updating config-extra.h timestamp very time one touches
Makefile.am, because it has a large dependency chain and makes
debugging of the Makefile inconvenient.

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/180
2019-06-14 09:21:24 +02:00
Beniamino Galvani e6628fa27c ipv6: add 'disabled' method
Add a new ipv6.method value 'disabled' that completely disables IPv6
for the interface.

https://bugzilla.redhat.com/show_bug.cgi?id=1643841
2019-06-11 16:22:04 +02:00
Thomas Haller 15d87f2da0 ifcfg-rh: drop unused "nm-inotify-helper.h"
This code is now unused.

Also, it does not seem state of the art to me
anymore.

Drop it, it could always be resurrected if need by, but maybe
GFileMonitor could be used instead.
2019-05-29 09:31:03 +02:00
Beniamino Galvani 9a410fc312 ifcfg-rh: use PKCS #12 private key also as client cert in reader
Before commit e3ac45c026 the reader set the private key in the
setting using the libnm function, which also set the key as client
certificate if it was in PKCS #12 format.

After the commit, existing connections with a PKCS #12 private key but
without a client certificate became invalid. Restore the old behavior.

Fixes: e3ac45c026 ('ifcfg-rh: don't use 802-1x certifcate setter functions')
2019-05-28 10:51:47 +02:00
Thomas Haller f809644866 build: don't link dispatcher with generated nmdbus-dispatcher bindings
We don't need it anymore.

Still, for tests let gdbus-codegen run and generate the sources and
compile them. We want to keep "dispatcher/nm-dispatcher.xml" and ensure
that it is still valid.
2019-05-27 12:39:25 +02:00
Thomas Haller 539dfbcc42 libnm: add "libnm-core/nm-team-utils.h" 2019-05-23 18:09:49 +02:00
Thomas Haller e64fdeeaf6 shared: add "shared/nm-glib-aux/nm-value-type.h"
Glib has GValue which used for boxing value.

Add NMValueType enum, which has a similar purpose, but it's much more
limited.

- contrary to GValue, the type must be tracked separately from the
  user-data. That is, the "user-data" is only a pointer of appropriate
  type, and the knowledge of the actual NMValueType is kept separately.
  This will be used to have a static list of meta-data that knows the
  value types, but keeping the values independent of this type
  information. With GValue this would not be possible.

- the use case is much more limited. Just support basic integers,
  boolean and strings. Nothing fancy.

Note that we already do something similar at muliple places. See for
example NMVariantAttributeSpec and nm_utils_team_link_watcher_to_string().
These could/should instead use NMValueType.
2019-05-23 18:09:49 +02:00
Thomas Haller f84e623732 shared: add "shared/nm-glib-aux/nm-json-aux.h"
This will be a set of JSON related utilities, that are independent of
libjansson.
2019-05-23 18:09:49 +02:00
Thomas Haller e7056d4efd build: don't statically link static libraries with other static libraries (6) 2019-05-22 20:04:08 +02:00
Thomas Haller 15e224fd59 build: don't statically link static libraries with other static libraries (5) 2019-05-22 20:04:08 +02:00
Thomas Haller 0a510ed1cf build: don't statically link static libraries with other static libraries (4) 2019-05-22 20:04:08 +02:00