During queued_ip_config_change(), we eventually call update_ip_config()
and ip4_config_merge_and_apply(). These functions read the IP configuration
from platform and setup the private ip4_config instance.
Trigger this initialization after constructing the device to setup
the IP configuration.
Before, for unmanaged devices we would not call ip4_config_merge_and_apply()
until the first platform change event.
Note that in the worst case we do some unnecessary work due to this,
because queued_ip_config_change() must already be robust to be called
at any time.
Since 0c136c1e2, we also track the default route for devices
without active-connection (unmanaged). They must not be returned
as best_config() or as best_device(), because the caller don't
expect unmanaged devices here.
This also gets closer to the original behavior of get_best_device()
before merging default-route-manager in d4417e3460
where we also would ignore devices depending on the state.
This fixes an assertion when having an interface unmanaged
and activating it externally:
#0 0x00007ffff6806187 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:55
#1 0x00007ffff6807dea in __GI_abort () at abort.c:89
#2 0x00007ffff6c0aec5 in g_assertion_message (domain=domain@entry=0x5332d5 "NetworkManager", file=file@entry=0x539460 "nm-default-route-manager.c", line=line@entry=1056, func=func@entry=0x539920 <__FUNCTION__.28934> "_ipx_get_best_config", message=message@entry=0x8c9cb0 "assertion failed: (req)") at gtestutils.c:2356
#3 0x00007ffff6c0af5a in g_assertion_message_expr (domain=domain@entry=0x5332d5 "NetworkManager", file=file@entry=0x539460 "nm-default-route-manager.c", line=line@entry=1056, func=func@entry=0x539920 <__FUNCTION__.28934> "_ipx_get_best_config", expr=expr@entry=0x53132f "req") at gtestutils.c:2371
#4 0x000000000049a196 in _ipx_get_best_config (self=<optimized out>, ignore_never_default=ignore_never_default@entry=1, out_ip_iface=out_ip_iface@entry=0x7fffffffd310, out_ac=out_ac@entry=0x0, out_device=0x0, out_vpn=0x7fffffffd318, vtable=0x7a0a00 <vtable_ip4>, vtable=0x7a0a00 <vtable_ip4>) at nm-default-route-manager.c:1056
#5 0x000000000049a3f6 in nm_default_route_manager_ip4_get_best_config (self=<optimized out>, ignore_never_default=ignore_never_default@entry=1, out_ip_iface=out_ip_iface@entry=0x7fffffffd310, out_ac=out_ac@entry=0x0, out_device=out_device@entry=0x0, out_vpn=out_vpn@entry=0x7fffffffd318) at nm-default-route-manager.c:1079
#6 0x00000000004b7518 in update_ip4_dns (self=0x7ecac0 [NMPolicy], out_vpn=0x7fffffffd318, out_device=0x0, out_ac=0x0, out_ip_iface=0x7fffffffd310, ignore_never_default=1) at nm-policy.c:390
#7 0x00000000004b7518 in update_ip4_dns (dns_mgr=0x8623a0 [NMDnsManager], policy=0x7ecac0 [NMPolicy]) at nm-policy.c:406
#8 0x00000000004b99d5 in device_ip4_config_changed (device=0x8844b0 [NMDeviceEthernet], new_config=0x908aa0 [NMIP4Config], old_config=0x908aa0 [NMIP4Config], user_data=0x7ecac0) at nm-policy.c:1260
#9 0x000000368f405d60 in ffi_call_unix64 () at /lib64/libffi.so.6
#10 0x000000368f4057d1 in ffi_call () at /lib64/libffi.so.6
#11 0x00007ffff6ee5b8c in g_cclosure_marshal_generic_va (closure=0x886a40, return_value=0x0, instance=0x8844b0, args_list=<optimized out>, marshal_data=0x0, n_params=2, param_types=0x87d3a0) at gclosure.c:1541
#12 0x00007ffff6ee5144 in _g_closure_invoke_va (closure=closure@entry=0x886a40, return_value=return_value@entry=0x0, instance=instance@entry=0x8844b0, args=args@entry=0x7fffffffd810, n_params=<optimized out>, param_types=0x87d3a0) at gclosure.c:831
#13 0x00007ffff6eff900 in g_signal_emit_valist (instance=0x8844b0, signal_id=<optimized out>, detail=0, var_args=var_args@entry=0x7fffffffd810) at gsignal.c:3201
#14 0x00007ffff6f0014f in g_signal_emit (instance=instance@entry=0x8844b0, signal_id=<optimized out>, detail=detail@entry=0) at gsignal.c:3348
#15 0x000000000044a1f4 in nm_device_set_ip4_config (self=self@entry=0x8844b0 [NMDeviceEthernet], new_config=new_config@entry=0x9089a0 [NMIP4Config], default_route_metric=default_route_metric@entry=100, commit=commit@entry=0, reason=reason@entry=0x0) at devices/nm-device.c:5866
#16 0x000000000044a5af in ip4_config_merge_and_apply (self=self@entry=0x8844b0 [NMDeviceEthernet], config=config@entry=0x0, commit=commit@entry=0, out_reason=out_reason@entry=0x0) at devices/nm-device.c:3037
#17 0x000000000044b4fd in update_ip_config (self=self@entry=0x8844b0 [NMDeviceEthernet], initial=initial@entry=0) at devices/nm-device.c:6617
#18 0x000000000044bc39 in queued_ip_config_change (user_data=<optimized out>) at devices/nm-device.c:6688
#19 0x00007ffff6be4e1b in g_main_context_dispatch (context=0x7ba3a0) at gmain.c:3122
#20 0x00007ffff6be4e1b in g_main_context_dispatch (context=context@entry=0x7ba3a0) at gmain.c:3737
#21 0x00007ffff6be51b0 in g_main_context_iterate (context=0x7ba3a0, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at gmain.c:3808
#22 0x00007ffff6be54d2 in g_main_loop_run (loop=0x7ba460) at gmain.c:4002
#23 0x000000000043291d in main (argc=1, argv=0x7fffffffdef8) at main.c:442
Fixes: da708059da
Enum types larger then the native 'int' type are undefined behavior
according to C standard. Assert that our compiler does the right thing.
the expression that defines the value of an enumeration constant shall
be an integer constant expression that has a value representable as an
int
We trigger a new solicitation upon seeing the new token. Kernel triggers one
too, but that one is of no use to us, since the advertisement might arrive sooner
than we learn about the token change.
Even more eagerly pickup external default routes from the device.
For assumed devices we already picked up the default route.
(a) For assumed devices we already did not enforce the default route at all.
Instead it was always picked up by from the actualy system
configuration. Note that this is the case for assumed-generated
connections and for assuming existing connections.
That means that when NM assumes a connection at startup, it will never
actively manage the default route on that interface. It will only react
on what is present.
(b) For managed devices that have by configuration no default route, still pick up
the default route. That means, that even a device that is managed and
never-default=yes, can have the default route -- if configured externally.
(c) Only during a commit phase (i.e. when we have new configuraiton to be
applied), we enforce the default route or its absence.
(d) During any IP change event from platform, we again pickup whatever
is present. That means if you remove the default route from a managed
interface, NM will not re-add it until anything triggers (c).
This also means, that during the commit phase, we add default routes as
'synced' to the default-route-manager, but the following event from platform,
will change the route entry immediately to 'non-synced'. That is
expected and correct.
When receiving IP changes via platform event, remove all missing
addresses and routes from our internal configurations (such as
wwan, vpn, dhcp).
The effect is that on the next commit, those addresses and routes will
not be re-added as they were explicitly removed by the user.
However on a new DHCP lease or similar events, the addresses will
be added anew.
Another important improvement is that the NMIPxConfig of the active
device reflects when addresses or routes get removed externally. Before
we would continue to expose those entires although they were not
actually configured on the device.
https://bugzilla.gnome.org/show_bug.cgi?id=740443
In the IPv4 case, we check whether we have a direct route to the gateway
also by looking at the configured addresses/subnets. That is correct,
because every IPv4 address also implies a subnet route.
For IPv6, we explicitly add all subnet routes manually (noprefixroute),
hence, we have a direct route exactly if we have it in our list.
Regardless of the configured IPv6 prefixes.
The previous syntax (s/S for synced, n/N for never-default) is confusing.
Indicate 'never-default' by '0', vs. '1'.
Indicated synced/non-synced as '+sync' and '-sync'.
Since 03a5a85d, NMDeviceTeam was trying to use priv->teamd_pid to
decide whether a teamd_dbus_vanished() call indicated "teamd hasn't
been started yet" or "teamd was previously started and has now
exited". But this resulted in a race condition, where at startup, a
device could call g_dbus_watch_name(), then launch teamd (causing
teamd_pid to get set), and then have gdbus report that teamd hasn't
been started yet before the newly-launched teamd managed to grab the
bus name. Since teamd_pid would already be set when
teamd_dbus_vanished() was called, it would decide that this meant
"teamd was previously started and has now exited", so it would call
teamd_cleanup(), killing the just-started teamd process.
Fix this by having teamd_dbus_vanished() check priv->tdc instead,
which doesn't get set until after the first teamd_dbus_appeared()
call.
We forgot to include the BRIDGE, so that bridge
devices got a default priority (route-metric) of 950
Add it between VLAN and MODEM type.
Also return a different metric for UNKNOWN
device types, but these priorities are not
actually expected.
ModemManager needs to have CLOCAL set in the TTY termios configuration, in order
to notify the kernel that modem control lines are not in effect (e.g. so that a
transition to LOW in the DCD input control line doesn't trigger a hangup in the
TTY).
pppd in the other hand, needs CLOCAL unset in order to have proper modem control
lines in effect during the PPP session. So, when pppd starts it will store the
original termios settings, and before exiting it will restore the original
settings in the TTY. In other words, if CLOCAL was set before launching pppd,
CLOCAL will be also set after pppd exits.
Now, in order for this sequence to work correctly, NetworkManager also needs to
make sure that ModemManager is notified about the disconnection only after pppd
has really finished re-configuring the TTY.
https://bugzilla.gnome.org/show_bug.cgi?id=734347
----------------------
Once the patch is applied, we will be making sure that ModemManager is only
notified about the disconnection AFTER pppd has fully exited:
NetworkManager[27589]: <info> (ttyUSB2): device state change: activated -> deactivating (reason 'user-requested') [100 110 39]
Terminating on signal 15
nm-pppd-plugin-Message: nm-ppp-plugin: (nm_phasechange): status 10 / phase 'terminate'
nm-pppd-plugin-Message: nm-ppp-plugin: (nm_phasechange): status 8 / phase 'network'
Connect time 0.3 minutes.
Sent 56 bytes, received 0 bytes.
nm-pppd-plugin-Message: nm-ppp-plugin: (nm_phasechange): status 5 / phase 'establish'
nm-pppd-plugin-Message: nm-ppp-plugin: (nm_phasechange): status 11 / phase 'disconnect'
Connection terminated.
nm-pppd-plugin-Message: nm-ppp-plugin: (nm_phasechange): status 1 / phase 'dead'
nm-pppd-plugin-Message: nm-ppp-plugin: (nm_exit_notify): cleaning up
NetworkManager[27589]: <warn> pppd pid 27617 exited with error: pppd received a signal
NetworkManager[27589]: <info> (ttyUSB2): modem state changed, 'connected' --> 'disconnecting' (reason: user-requested)
NetworkManager[27589]: <info> (ttyUSB2): modem state changed, 'disconnecting' --> 'registered' (reason: user-requested)
NetworkManager[27589]: <info> (ttyUSB2) modem deactivation finished
NetworkManager[27589]: <info> (ttyUSB2): device state change: deactivating -> disconnected (reason 'user-requested') [110 30 39]
NetworkManager[27589]: <info> (ttyUSB2): deactivating device (reason 'user-requested') [39]
Add nm_utils_setpgid() as a g_spawn*() child setup function for
calling setpgid(), and use it where appropriate rather than
reimplementing it every time.
There's no point in calling setpgid() on short-lived processes, so
remove the setpgid() calls when spawning dispatcher scripts, iptables,
iscsiadmin, and netconf.
nm-iface-helper originally used the same pthread_sigmask()-based
signal handling as NetworkManager, but was then switched to using
g_unix_signal_add(). But a little bit of unnecessary code remained.
Replace the pthread_sigwait()-based signal handling with
g_unix_signal_add()-based handling, and get rid of all the
now-unnecessary calls to nm_unblock_posix_signals() when spawning
subprocesses.
As a bonus, this also fixes the "^C in gdb kills NM too" bug.
Testing WWAN connections through a Nokia Series 40 phone, addresses of family
AF_PHONET end up triggering an assert() in object_has_ifindex(), just because
object_type_from_nl_object() only handles AF_INET and AF_INET6 address.
In order to avoid this kind of problems, we'll try to make sure that the object
caches kept by NM only store known object types.
(fixup by dcbw to use cached passed to cache_remove_unknown())
https://bugzilla.gnome.org/show_bug.cgi?id=742928
Connect: ppp0 <--> /dev/ttyACM0
nm-pppd-plugin-Message: nm-ppp-plugin: (nm_phasechange): status 5 / phase 'establish'
NetworkManager[27434]: <info> (ppp0): new Generic device (driver: 'unknown' ifindex: 12)
NetworkManager[27434]: <info> (ppp0): exported as /org/freedesktop/NetworkManager/Devices/4
[Thread 0x7ffff1ecf700 (LWP 27439) exited]
NetworkManager[27434]: <info> (ttyACM0): device state change: ip-config -> deactivating (reason 'user-requested') [70 110 39]
Terminating on signal 15
nm-pppd-plugin-Message: nm-ppp-plugin: (nm_phasechange): status 10 / phase 'terminate'
**
NetworkManager:ERROR:platform/nm-linux-platform.c:1534:object_has_ifindex: code should not be reached
Program received signal SIGABRT, Aborted.
0x00007ffff4692a97 in raise () from /usr/lib/libc.so.6
(gdb) bt
#0 0x00007ffff4692a97 in raise () from /usr/lib/libc.so.6
#1 0x00007ffff4693e6a in abort () from /usr/lib/libc.so.6
#2 0x00007ffff4c8d7f5 in g_assertion_message () from /usr/lib/libglib-2.0.so.0
#3 0x00007ffff4c8d88a in g_assertion_message_expr () from /usr/lib/libglib-2.0.so.0
#4 0x0000000000472b91 in object_has_ifindex (object=0x8a8320, ifindex=12) at platform/nm-linux-platform.c:1534
#5 0x0000000000472bec in check_cache_items (platform=0x7fe8a0, cache=0x7fda30, ifindex=12) at platform/nm-linux-platform.c:1549
#6 0x0000000000472de3 in announce_object (platform=0x7fe8a0, object=0x8a8c30, change_type=NM_PLATFORM_SIGNAL_REMOVED, reason=NM_PLATFORM_REASON_EXTERNAL) at platform/nm-linux-platform.c:1617
#7 0x0000000000473dd2 in event_notification (msg=0x8a7970, user_data=0x7fe8a0) at platform/nm-linux-platform.c:1992
#8 0x00007ffff5ee14de in nl_recvmsgs_report () from /usr/lib/libnl-3.so.200
#9 0x00007ffff5ee1849 in nl_recvmsgs () from /usr/lib/libnl-3.so.200
#10 0x00000000004794df in event_handler (channel=0x7fc930, io_condition=G_IO_IN, user_data=0x7fe8a0) at platform/nm-linux-platform.c:4152
#11 0x00007ffff4c6791d in g_main_context_dispatch () from /usr/lib/libglib-2.0.so.0
#12 0x00007ffff4c67cf8 in ?? () from /usr/lib/libglib-2.0.so.0
#13 0x00007ffff4c68022 in g_main_loop_run () from /usr/lib/libglib-2.0.so.0
#14 0x00000000004477ee in main (argc=1, argv=0x7fffffffeaa8) at main.c:447
(gdb) fr 4
#4 0x0000000000472b91 in object_has_ifindex (object=0x8a8320, ifindex=12) at platform/nm-linux-platform.c:1534
1534 g_assert_not_reached ();
The address might be zero-size, and therefore nl_addr_get_binary_addr()
returns a pointer to a zero-size array. We don't want to read past the
end of that array. Since zero-size addresses really mean an address
of all zeros, just make that happen.
As an additional optimization, if the prefix length is zero, the whole
address is host bits and should be cleared.
==30286== Invalid read of size 4
==30286== at 0x478090: clear_host_address (nm-linux-platform.c:3786)
==30286== by 0x4784D4: route_search_cache (nm-linux-platform.c:3883)
==30286== by 0x4785A1: refresh_route (nm-linux-platform.c:3901)
==30286== by 0x4787B6: ip4_route_delete (nm-linux-platform.c:3978)
==30286== by 0x47F674: nm_platform_ip4_route_delete (nm-platform.c:1980)
==30286== by 0x4B279D: _v4_platform_route_delete_default (nm-default-route-manager.c:1122)
==30286== by 0x4AEF03: _platform_route_sync_flush (nm-default-route-manager.c:320)
==30286== by 0x4B043E: _resync_all (nm-default-route-manager.c:574)
==30286== by 0x4B0CA7: _entry_at_idx_remove (nm-default-route-manager.c:631)
==30286== by 0x4B1A66: _ipx_update_default_route (nm-default-route-manager.c:806)
==30286== by 0x4B1A9C: nm_default_route_manager_ip4_update_default_route (nm-default-route-manager.c:813)
==30286== by 0x45C3BC: _cleanup_generic_post (nm-device.c:7143)
==30286== Address 0xee33514 is 0 bytes after a block of size 20 alloc'd
==30286== at 0x4C2C080: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==30286== by 0x6B2B0B1: nl_addr_alloc (in /usr/lib/libnl-3.so.200.20.0)
==30286== by 0x6B2B0E3: nl_addr_build (in /usr/lib/libnl-3.so.200.20.0)
==30286== by 0x6B2B181: nl_addr_clone (in /usr/lib/libnl-3.so.200.20.0)
==30286== by 0x66DB0D7: ??? (in /usr/lib/libnl-route-3.so.200.20.0)
==30286== by 0x6B33CE6: nl_object_clone (in /usr/lib/libnl-3.so.200.20.0)
==30286== by 0x6B2D303: nl_cache_add (in /usr/lib/libnl-3.so.200.20.0)
==30286== by 0x472E55: refresh_object (nm-linux-platform.c:1735)
==30286== by 0x473137: add_object (nm-linux-platform.c:1795)
==30286== by 0x478373: ip4_route_add (nm-linux-platform.c:3846)
==30286== by 0x47F375: nm_platform_ip4_route_add (nm-platform.c:1939)
==30286== by 0x4AEC06: _platform_route_sync_add (nm-default-route-manager.c:254)
https://bugzilla.gnome.org/show_bug.cgi?id=742937
Testing WWAN connections through a Nokia Series 40 phone, addresses of family
AF_PHONET end up triggering an assert() in object_has_ifindex(), just because
object_type_from_nl_object() only handles AF_INET and AF_INET6 address.
In order to avoid this kind of problems, we'll try to make sure that the object
caches kept by NM only store known object types.
https://bugzilla.gnome.org/show_bug.cgi?id=742928
Connect: ppp0 <--> /dev/ttyACM0
nm-pppd-plugin-Message: nm-ppp-plugin: (nm_phasechange): status 5 / phase 'establish'
NetworkManager[27434]: <info> (ppp0): new Generic device (driver: 'unknown' ifindex: 12)
NetworkManager[27434]: <info> (ppp0): exported as /org/freedesktop/NetworkManager/Devices/4
[Thread 0x7ffff1ecf700 (LWP 27439) exited]
NetworkManager[27434]: <info> (ttyACM0): device state change: ip-config -> deactivating (reason 'user-requested') [70 110 39]
Terminating on signal 15
nm-pppd-plugin-Message: nm-ppp-plugin: (nm_phasechange): status 10 / phase 'terminate'
**
NetworkManager:ERROR:platform/nm-linux-platform.c:1534:object_has_ifindex: code should not be reached
Program received signal SIGABRT, Aborted.
0x00007ffff4692a97 in raise () from /usr/lib/libc.so.6
(gdb) bt
#0 0x00007ffff4692a97 in raise () from /usr/lib/libc.so.6
#1 0x00007ffff4693e6a in abort () from /usr/lib/libc.so.6
#2 0x00007ffff4c8d7f5 in g_assertion_message () from /usr/lib/libglib-2.0.so.0
#3 0x00007ffff4c8d88a in g_assertion_message_expr () from /usr/lib/libglib-2.0.so.0
#4 0x0000000000472b91 in object_has_ifindex (object=0x8a8320, ifindex=12) at platform/nm-linux-platform.c:1534
#5 0x0000000000472bec in check_cache_items (platform=0x7fe8a0, cache=0x7fda30, ifindex=12) at platform/nm-linux-platform.c:1549
#6 0x0000000000472de3 in announce_object (platform=0x7fe8a0, object=0x8a8c30, change_type=NM_PLATFORM_SIGNAL_REMOVED, reason=NM_PLATFORM_REASON_EXTERNAL) at platform/nm-linux-platform.c:1617
#7 0x0000000000473dd2 in event_notification (msg=0x8a7970, user_data=0x7fe8a0) at platform/nm-linux-platform.c:1992
#8 0x00007ffff5ee14de in nl_recvmsgs_report () from /usr/lib/libnl-3.so.200
#9 0x00007ffff5ee1849 in nl_recvmsgs () from /usr/lib/libnl-3.so.200
#10 0x00000000004794df in event_handler (channel=0x7fc930, io_condition=G_IO_IN, user_data=0x7fe8a0) at platform/nm-linux-platform.c:4152
#11 0x00007ffff4c6791d in g_main_context_dispatch () from /usr/lib/libglib-2.0.so.0
#12 0x00007ffff4c67cf8 in ?? () from /usr/lib/libglib-2.0.so.0
#13 0x00007ffff4c68022 in g_main_loop_run () from /usr/lib/libglib-2.0.so.0
#14 0x00000000004477ee in main (argc=1, argv=0x7fffffffeaa8) at main.c:447
(gdb) fr 4
#4 0x0000000000472b91 in object_has_ifindex (object=0x8a8320, ifindex=12) at platform/nm-linux-platform.c:1534
1534 g_assert_not_reached ();
Don't start an automatic connectivity check right when NMManager tells
us we're online; only do it if the manager doesn't request an explicit
connectivity check immediately afterward.
Merge the two nm_connectivity_set_online() calls into one, after
tweaking NMConnectivity to always update its internal state before
alerting callers to the new state.
When a connection has finished activating, but we don't know yet that
we have full connectivity, then find_best_device_state() should return
CONNECTED_SITE, not CONNECTING. Fixes a bug where the manager state
would repeatedly switch between those two states.
nm-connectivity was logging both "started" and "finished" for periodic
connectivity checks, but was only logging "finished" for manual ones,
which made the logs look weird. Fix it to log both periodic and manual
starts, and differentiate them.
Also add some additional logging to indicate when set_online() is
called, and when :state changes.
Custom IP ranges for shared connection were implemeted in bgo #6759732
(commit 32a001f526). The first IP address
is used and a range is calculated.
However, the commit missed to update ifcfg-rh plugin to read the address.
Test case:
* use ifcfg-rh plugin for NetworkManager
$ nmcli con add type eth con-name shared-ip ifname eth0
$ nmcli con mod shared-ip ipv4.addresses 9.8.7.6/24 ipv4.method shared
$ nmcli con show shared-ip
$ nmcli con show shared-ip <--- ip address 9.8.7.6 was missing
https://bugzilla.redhat.com/show_bug.cgi?id=1174632
This was not really an error, because NMIfcfgConnection would not
watch the files if monitoring is not enabled. Still do it, because
it feels more correct.