diff options
author | Thomas Haller <thaller@redhat.com> | 2020-09-18 15:26:49 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2020-09-18 15:26:49 +0200 |
commit | 86f2ea66f55562722cab7a49fd76021b38dac988 (patch) | |
tree | c87e440b2ef19d2767184b2005827b6b33fae938 | |
parent | 026389fc1f14ed7a121a89f409e919582b88af5b (diff) | |
parent | 5e841433786ad6b2de7fe4cf8f6432ca6f925d71 (diff) | |
download | NetworkManager-86f2ea66f55562722cab7a49fd76021b38dac988.tar.gz |
l3cfg: merge branch 'th/l3cfg-9'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/626
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | introspection/org.freedesktop.NetworkManager.Device.xml | 2 | ||||
-rw-r--r-- | libnm-core/nm-utils.c | 12 | ||||
-rw-r--r-- | shared/nm-glib-aux/nm-shared-utils.c | 28 | ||||
-rw-r--r-- | shared/nm-glib-aux/nm-shared-utils.h | 2 | ||||
-rw-r--r-- | src/devices/nm-device.c | 96 | ||||
-rw-r--r-- | src/ndisc/nm-fake-ndisc.c | 15 | ||||
-rw-r--r-- | src/ndisc/nm-lndp-ndisc.c | 119 | ||||
-rw-r--r-- | src/ndisc/nm-lndp-ndisc.h | 12 | ||||
-rw-r--r-- | src/ndisc/nm-ndisc.c | 220 | ||||
-rw-r--r-- | src/ndisc/nm-ndisc.h | 37 | ||||
-rw-r--r-- | src/ndisc/tests/test-ndisc-linux.c | 16 | ||||
-rw-r--r-- | src/nm-dbus-utils.c | 22 | ||||
-rw-r--r-- | src/nm-iface-helper.c | 17 | ||||
-rw-r--r-- | src/nm-l3-config-data.c | 213 | ||||
-rw-r--r-- | src/nm-l3-config-data.h | 32 | ||||
-rw-r--r-- | src/nm-l3cfg.c | 9 | ||||
-rw-r--r-- | src/nm-manager.c | 2 | ||||
-rw-r--r-- | src/platform/nm-platform.c | 2 |
19 files changed, 709 insertions, 149 deletions
@@ -15,6 +15,8 @@ USE AT YOUR OWN RISK. NOT RECOMMENDED FOR PRODUCTION USE! setting and runtime detection. "resolvconf" and "netconfig" are only considered iff NetworkManager was built with the respective options enabled. +* The long deprecated D-Bus property "Ip4Address" on "org.freedesktop.NetworkManager.Device" + interface is not defunct and always returns zero. ============================================= NetworkManager-1.26 diff --git a/introspection/org.freedesktop.NetworkManager.Device.xml b/introspection/org.freedesktop.NetworkManager.Device.xml index f1ab3db53b..adcdaec163 100644 --- a/introspection/org.freedesktop.NetworkManager.Device.xml +++ b/introspection/org.freedesktop.NetworkManager.Device.xml @@ -100,7 +100,7 @@ Ip4Address: DEPRECATED; use the 'Addresses' property of the 'Ip4Config' object - instead. + instead. This property always returns 0.0.0.0 (numeric 0) as address. --> <property name="Ip4Address" type="u" access="read"/> diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index c0913eea98..2058d110df 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -4878,7 +4878,7 @@ nm_utils_is_uuid (const char *str) return FALSE; } -static char _nm_utils_inet_ntop_buffer[NM_UTILS_INET_ADDRSTRLEN]; +static _nm_thread_local char _nm_utils_inet_ntop_buffer[NM_UTILS_INET_ADDRSTRLEN]; /** * nm_utils_inet4_ntop: (skip) @@ -4888,8 +4888,9 @@ static char _nm_utils_inet_ntop_buffer[NM_UTILS_INET_ADDRSTRLEN]; * characters. If set to %NULL, it will return a pointer to an internal, static * buffer (shared with nm_utils_inet6_ntop()). Beware, that the internal * buffer will be overwritten with ever new call of nm_utils_inet4_ntop() or - * nm_utils_inet6_ntop() that does not provide its own @dst buffer. Also, - * using the internal buffer is not thread safe. When in doubt, pass your own + * nm_utils_inet6_ntop() that does not provide its own @dst buffer. Since + * 1.28, the internal buffer is thread local and thus thread safe. Before + * it was not thread safe. When in doubt, pass your own * @dst buffer to avoid these issues. * * Wrapper for inet_ntop. @@ -4916,8 +4917,9 @@ nm_utils_inet4_ntop (in_addr_t inaddr, char *dst) * characters. If set to %NULL, it will return a pointer to an internal, static * buffer (shared with nm_utils_inet4_ntop()). Beware, that the internal * buffer will be overwritten with ever new call of nm_utils_inet4_ntop() or - * nm_utils_inet6_ntop() that does not provide its own @dst buffer. Also, - * using the internal buffer is not thread safe. When in doubt, pass your own + * nm_utils_inet6_ntop() that does not provide its own @dst buffer. Since + * 1.28, the internal buffer is thread local and thus thread safe. Before + * it was not thread safe. When in doubt, pass your own * @dst buffer to avoid these issues. * * Wrapper for inet_ntop. diff --git a/shared/nm-glib-aux/nm-shared-utils.c b/shared/nm-glib-aux/nm-shared-utils.c index 242719ffed..c5c9576fae 100644 --- a/shared/nm-glib-aux/nm-shared-utils.c +++ b/shared/nm-glib-aux/nm-shared-utils.c @@ -405,6 +405,34 @@ nm_utils_gbytes_to_variant_ay (GBytes *bytes) /*****************************************************************************/ +#define _variant_singleton_get(create_variant) \ + ({ \ + static GVariant *_singleton = NULL; \ + GVariant *_v; \ + \ + again: \ + _v = g_atomic_pointer_get (&_singleton); \ + if (G_UNLIKELY (!_v)) { \ + _v = (create_variant); \ + nm_assert (_v); \ + nm_assert (g_variant_is_floating (_v)); \ + g_variant_ref_sink (_v); \ + if (!g_atomic_pointer_compare_and_exchange (&_singleton, NULL, _v)) { \ + g_variant_unref (_v); \ + goto again; \ + } \ + } \ + _v; \ + }) + +GVariant * +nm_g_variant_singleton_u_0 (void) +{ + return _variant_singleton_get (g_variant_new_uint32 (0)); +} + +/*****************************************************************************/ + /* Convert a hash table with "char *" keys and values to an "a{ss}" GVariant. * The keys will be sorted asciibetically. * Returns a floating reference. diff --git a/shared/nm-glib-aux/nm-shared-utils.h b/shared/nm-glib-aux/nm-shared-utils.h index e413531fd8..f09c1580cd 100644 --- a/shared/nm-glib-aux/nm-shared-utils.h +++ b/shared/nm-glib-aux/nm-shared-utils.h @@ -1249,6 +1249,8 @@ char *nm_utils_str_utf8safe_unescape_cp (const char *str, NMUtilsStrUtf8SafeFlag char *nm_utils_str_utf8safe_escape_take (char *str, NMUtilsStrUtf8SafeFlags flags); +GVariant *nm_g_variant_singleton_u_0 (void); + static inline void nm_g_variant_unref_floating (GVariant *var) { diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index f0fe5a0385..bd14099015 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -377,8 +377,6 @@ typedef struct _NMDevicePrivate { GCancellable *deactivating_cancellable; - guint32 ip4_address; - NMActRequest * queued_act_request; bool queued_act_request_is_waiting_for_carrier:1; NMDBusTrackObjPath act_request; @@ -1179,7 +1177,7 @@ out_good: return duid_out; } -static gint32 +static guint32 _prop_get_ipv6_ra_timeout (NMDevice *self) { NMConnection *connection; @@ -1191,9 +1189,9 @@ _prop_get_ipv6_ra_timeout (NMDevice *self) connection = nm_device_get_applied_connection (self); timeout = nm_setting_ip6_config_get_ra_timeout (NM_SETTING_IP6_CONFIG (nm_connection_get_setting_ip6_config (connection))); - nm_assert (timeout >= 0); - if (timeout) + if (timeout > 0) return timeout; + nm_assert (timeout == 0); return nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, NM_CON_DEFAULT ("ipv6.ra-timeout"), @@ -10981,15 +10979,6 @@ addrconf6_start_with_link_ready (NMDevice *self) return; } -static NMNDiscNodeType -ndisc_node_type (NMDevice *self) -{ - if (nm_streq (nm_device_get_effective_ip_config_method (self, AF_INET6), - NM_SETTING_IP4_CONFIG_METHOD_SHARED)) - return NM_NDISC_NODE_TYPE_ROUTER; - return NM_NDISC_NODE_TYPE_HOST; -} - static gboolean addrconf6_start (NMDevice *self, NMSettingIP6ConfigPrivacy use_tempaddr) { @@ -10999,6 +10988,12 @@ addrconf6_start (NMDevice *self, NMSettingIP6ConfigPrivacy use_tempaddr) GError *error = NULL; NMUtilsStableType stable_type; const char *stable_id; + NMNDiscNodeType node_type; + int max_addresses; + int router_solicitations; + int router_solicitation_interval; + guint32 ra_timeout; + guint32 default_ra_timeout; connection = nm_device_get_applied_connection (self); g_assert (connection); @@ -11012,6 +11007,27 @@ addrconf6_start (NMDevice *self, NMSettingIP6ConfigPrivacy use_tempaddr) s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting_ip6_config (connection)); g_assert (s_ip6); + if (nm_streq (nm_device_get_effective_ip_config_method (self, AF_INET6), + NM_SETTING_IP4_CONFIG_METHOD_SHARED)) + node_type = NM_NDISC_NODE_TYPE_ROUTER; + else + node_type = NM_NDISC_NODE_TYPE_HOST; + + nm_lndp_ndisc_get_sysctl (nm_device_get_platform (self), + nm_device_get_ip_iface (self), + &max_addresses, + &router_solicitations, + &router_solicitation_interval, + &default_ra_timeout); + + if (node_type == NM_NDISC_NODE_TYPE_ROUTER) + ra_timeout = 0u; + else { + ra_timeout = _prop_get_ipv6_ra_timeout (self); + if (ra_timeout == 0u) + ra_timeout = default_ra_timeout; + } + stable_id = _prop_get_connection_stable_id (self, connection, &stable_type); priv->ndisc = nm_lndp_ndisc_new (nm_device_get_platform (self), nm_device_get_ip_ifindex (self), @@ -11019,8 +11035,11 @@ addrconf6_start (NMDevice *self, NMSettingIP6ConfigPrivacy use_tempaddr) stable_type, stable_id, nm_setting_ip6_config_get_addr_gen_mode (s_ip6), - ndisc_node_type (self), - _prop_get_ipv6_ra_timeout (self), + node_type, + max_addresses, + router_solicitations, + router_solicitation_interval, + ra_timeout, &error); if (!priv->ndisc) { _LOGE (LOGD_IP6, "addrconf6: failed to start neighbor discovery: %s", error->message); @@ -11059,7 +11078,10 @@ addrconf6_cleanup (NMDevice *self) applied_config_clear (&priv->ac_ip6_config); nm_clear_pointer (&priv->rt6_temporary_not_available, g_hash_table_unref); nm_clear_g_source (&priv->rt6_temporary_not_available_id); - g_clear_object (&priv->ndisc); + if (priv->ndisc) { + nm_ndisc_stop (priv->ndisc); + g_clear_object (&priv->ndisc); + } } /*****************************************************************************/ @@ -12276,24 +12298,6 @@ dnsmasq_cleanup (NMDevice *self) priv->dnsmasq_manager = NULL; } -static void -_update_ip4_address (NMDevice *self) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - const NMPlatformIP4Address *address; - - g_return_if_fail (NM_IS_DEVICE (self)); - - if ( priv->ip_config_4 - && ip_config_valid (priv->state) - && (address = nm_ip4_config_get_first_address (priv->ip_config_4))) { - if (address->address != priv->ip4_address) { - priv->ip4_address = address->address; - _notify (self, PROP_IP4_ADDRESS); - } - } -} - gboolean nm_device_is_nm_owned (NMDevice *self) { @@ -13725,9 +13729,6 @@ nm_device_set_ip_config (NMDevice *self, if (has_changes) { - if (IS_IPv4) - _update_ip4_address (self); - if (old_config != priv->ip_config_x[IS_IPv4]) _notify (self, IS_IPv4 ? PROP_IP4_CONFIG : PROP_IP6_CONFIG); @@ -14252,8 +14253,6 @@ nm_device_bring_up (NMDevice *self, gboolean block, gboolean *no_firmware) /* Can only get HW address of some devices when they are up */ nm_device_update_hw_address (self); - _update_ip4_address (self); - /* when the link comes up, we must restore IP configuration if necessary. */ if (priv->ip_state_4 == NM_DEVICE_IP_STATE_DONE) { if (!ip_config_merge_and_apply (self, AF_INET, TRUE)) @@ -15975,12 +15974,6 @@ _cleanup_generic_post (NMDevice *self, CleanupType cleanup_type) act_request_set (self, NULL); } - /* Clear legacy IPv4 address property */ - if (priv->ip4_address) { - priv->ip4_address = 0; - _notify (self, PROP_IP4_ADDRESS); - } - if (cleanup_type == CLEANUP_TYPE_DECONFIGURE) { /* Check if the device was deactivated, and if so, delete_link. * Don't call delete_link synchronously because we are currently @@ -17794,7 +17787,7 @@ get_property (GObject *object, guint prop_id, g_value_set_uint (value, (priv->capabilities & ~NM_DEVICE_CAP_INTERNAL_MASK)); break; case PROP_IP4_ADDRESS: - g_value_set_uint (value, priv->ip4_address); + g_value_set_variant (value, nm_g_variant_singleton_u_0 ()); break; case PROP_CARRIER: g_value_set_boolean (value, priv->carrier); @@ -18507,10 +18500,11 @@ nm_device_class_init (NMDeviceClass *klass) G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); obj_properties[PROP_IP4_ADDRESS] = - g_param_spec_uint (NM_DEVICE_IP4_ADDRESS, "", "", - 0, G_MAXUINT32, 0, /* FIXME */ - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); + g_param_spec_variant (NM_DEVICE_IP4_ADDRESS, "", "", + G_VARIANT_TYPE_UINT32, + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); obj_properties[PROP_IP4_CONFIG] = g_param_spec_string (NM_DEVICE_IP4_CONFIG, "", "", NULL, diff --git a/src/ndisc/nm-fake-ndisc.c b/src/ndisc/nm-fake-ndisc.c index 5f4594b983..14ef18d58b 100644 --- a/src/ndisc/nm-fake-ndisc.c +++ b/src/ndisc/nm-fake-ndisc.c @@ -337,6 +337,14 @@ start (NMNDisc *ndisc) priv->receive_ra_id = g_timeout_add_seconds (ra->when, receive_ra, ndisc); } +static void +stop (NMNDisc *ndisc) +{ + NMFakeNDiscPrivate *priv = NM_FAKE_NDISC_GET_PRIVATE (ndisc); + + nm_clear_g_source (&priv->receive_ra_id); +} + void nm_fake_ndisc_emit_new_ras (NMFakeNDisc *self) { @@ -360,6 +368,10 @@ nm_fake_ndisc_new (int ifindex, const char *ifname) NM_NDISC_NODE_TYPE, (int) NM_NDISC_NODE_TYPE_HOST, NM_NDISC_STABLE_TYPE, (int) NM_UTILS_STABLE_TYPE_UUID, NM_NDISC_NETWORK_ID, "fake", + NM_NDISC_MAX_ADDRESSES, NM_NDISC_MAX_ADDRESSES_DEFAULT, + NM_NDISC_ROUTER_SOLICITATIONS, NM_NDISC_ROUTER_SOLICITATIONS_DEFAULT, + NM_NDISC_ROUTER_SOLICITATION_INTERVAL, NM_NDISC_ROUTER_SOLICITATION_INTERVAL_DEFAULT, + NM_NDISC_RA_TIMEOUT, 30u, NULL); } @@ -384,7 +396,8 @@ nm_fake_ndisc_class_init (NMFakeNDiscClass *klass) object_class->dispose = dispose; - ndisc_class->start = start; + ndisc_class->start = start; + ndisc_class->stop = stop; ndisc_class->send_rs = send_rs; signals[RS_SENT] = diff --git a/src/ndisc/nm-lndp-ndisc.c b/src/ndisc/nm-lndp-ndisc.c index 25666c2e45..654d9693ae 100644 --- a/src/ndisc/nm-lndp-ndisc.c +++ b/src/ndisc/nm-lndp-ndisc.c @@ -535,6 +535,36 @@ start (NMNDisc *ndisc) } } +static void +_cleanup (NMNDisc *ndisc) +{ + NMLndpNDiscPrivate *priv = NM_LNDP_NDISC_GET_PRIVATE (ndisc); + + nm_clear_g_source_inst (&priv->event_source); + + if (priv->ndp) { + switch (nm_ndisc_get_node_type (ndisc)) { + case NM_NDISC_NODE_TYPE_HOST: + ndp_msgrcv_handler_unregister (priv->ndp, receive_ra, NDP_MSG_RA, nm_ndisc_get_ifindex (ndisc), ndisc); + break; + case NM_NDISC_NODE_TYPE_ROUTER: + ndp_msgrcv_handler_unregister (priv->ndp, receive_rs, NDP_MSG_RS, nm_ndisc_get_ifindex (ndisc), ndisc); + break; + default: + nm_assert_not_reached (); + break; + } + ndp_close (priv->ndp); + priv->ndp = NULL; + } +} + +static void +stop (NMNDisc *ndisc) +{ + _cleanup (ndisc); +} + /*****************************************************************************/ static int @@ -550,6 +580,51 @@ ipv6_sysctl_get (NMPlatform *platform, const char *ifname, const char *property, defval); } +void +nm_lndp_ndisc_get_sysctl (NMPlatform *platform, + const char *ifname, + int *out_max_addresses, + int *out_router_solicitations, + int *out_router_solicitation_interval, + guint32 *out_default_ra_timeout) +{ + int router_solicitation_interval = 0; + int router_solicitations = 0; + + if (out_max_addresses) { + *out_max_addresses = ipv6_sysctl_get (platform, + ifname, + "max_addresses", + 0, + G_MAXINT32, + NM_NDISC_MAX_ADDRESSES_DEFAULT); + } + if (out_router_solicitations || out_default_ra_timeout) { + router_solicitations = ipv6_sysctl_get (platform, + ifname, + "router_solicitations", + 1, + G_MAXINT32, + NM_NDISC_ROUTER_SOLICITATIONS_DEFAULT); + NM_SET_OUT (out_router_solicitations, router_solicitations); + } + if (out_router_solicitation_interval || out_default_ra_timeout) { + router_solicitation_interval = ipv6_sysctl_get (platform, + ifname, + "router_solicitation_interval", + 1, + G_MAXINT32, + NM_NDISC_ROUTER_SOLICITATION_INTERVAL_DEFAULT); + NM_SET_OUT (out_router_solicitation_interval, router_solicitation_interval); + } + if (out_default_ra_timeout) { + *out_default_ra_timeout = NM_MAX ((((gint64) router_solicitations) * router_solicitation_interval) + 1, + 30); + } +} + +/*****************************************************************************/ + static void nm_lndp_ndisc_init (NMLndpNDisc *lndp_ndisc) { @@ -563,7 +638,10 @@ nm_lndp_ndisc_new (NMPlatform *platform, const char *network_id, NMSettingIP6ConfigAddrGenMode addr_gen_mode, NMNDiscNodeType node_type, - gint32 ra_timeout, + int max_addresses, + int router_solicitations, + int router_solicitation_interval, + guint32 ra_timeout, GError **error) { nm_auto_pop_netns NMPNetns *netns = NULL; @@ -586,16 +664,10 @@ nm_lndp_ndisc_new (NMPlatform *platform, NM_NDISC_NETWORK_ID, network_id, NM_NDISC_ADDR_GEN_MODE, (int) addr_gen_mode, NM_NDISC_NODE_TYPE, (int) node_type, - NM_NDISC_MAX_ADDRESSES, ipv6_sysctl_get (platform, ifname, - "max_addresses", - 0, G_MAXINT32, NM_NDISC_MAX_ADDRESSES_DEFAULT), - NM_NDISC_RA_TIMEOUT, (int) ra_timeout, - NM_NDISC_ROUTER_SOLICITATIONS, ipv6_sysctl_get (platform, ifname, - "router_solicitations", - 1, G_MAXINT32, NM_NDISC_ROUTER_SOLICITATIONS_DEFAULT), - NM_NDISC_ROUTER_SOLICITATION_INTERVAL, ipv6_sysctl_get (platform, ifname, - "router_solicitation_interval", - 1, G_MAXINT32, NM_NDISC_ROUTER_SOLICITATION_INTERVAL_DEFAULT), + NM_NDISC_MAX_ADDRESSES, max_addresses, + NM_NDISC_ROUTER_SOLICITATIONS, router_solicitations, + NM_NDISC_ROUTER_SOLICITATION_INTERVAL, router_solicitation_interval, + NM_NDISC_RA_TIMEOUT, (guint) ra_timeout, NULL); priv = NM_LNDP_NDISC_GET_PRIVATE (ndisc); @@ -617,24 +689,8 @@ static void dispose (GObject *object) { NMNDisc *ndisc = NM_NDISC (object); - NMLndpNDiscPrivate *priv = NM_LNDP_NDISC_GET_PRIVATE (ndisc); - nm_clear_g_source_inst (&priv->event_source); - - if (priv->ndp) { - switch (nm_ndisc_get_node_type (ndisc)) { - case NM_NDISC_NODE_TYPE_HOST: - ndp_msgrcv_handler_unregister (priv->ndp, receive_ra, NDP_MSG_RA, nm_ndisc_get_ifindex (ndisc), ndisc); - break; - case NM_NDISC_NODE_TYPE_ROUTER: - ndp_msgrcv_handler_unregister (priv->ndp, receive_rs, NDP_MSG_RS, nm_ndisc_get_ifindex (ndisc), ndisc); - break; - default: - g_assert_not_reached (); - } - ndp_close (priv->ndp); - priv->ndp = NULL; - } + _cleanup (ndisc); G_OBJECT_CLASS (nm_lndp_ndisc_parent_class)->dispose (object); } @@ -646,7 +702,8 @@ nm_lndp_ndisc_class_init (NMLndpNDiscClass *klass) NMNDiscClass *ndisc_class = NM_NDISC_CLASS (klass); object_class->dispose = dispose; - ndisc_class->start = start; - ndisc_class->send_rs = send_rs; - ndisc_class->send_ra = send_ra; + ndisc_class->start = start; + ndisc_class->stop = stop; + ndisc_class->send_rs = send_rs; + ndisc_class->send_ra = send_ra; } diff --git a/src/ndisc/nm-lndp-ndisc.h b/src/ndisc/nm-lndp-ndisc.h index 82e7b2de16..e15436e962 100644 --- a/src/ndisc/nm-lndp-ndisc.h +++ b/src/ndisc/nm-lndp-ndisc.h @@ -28,7 +28,17 @@ NMNDisc *nm_lndp_ndisc_new (NMPlatform *platform, const char *network_id, NMSettingIP6ConfigAddrGenMode addr_gen_mode, NMNDiscNodeType node_type, - gint32 ra_timeout, + int max_addresses, + int router_solicitations, + int router_solicitation_interval, + guint32 ra_timeout, GError **error); +void nm_lndp_ndisc_get_sysctl (NMPlatform *platform, + const char *ifname, + int *out_max_addresses, + int *out_router_solicitations, + int *out_router_solicitation_interval, + guint32 *out_default_ra_timeout); + #endif /* __NETWORKMANAGER_LNDP_NDISC_H__ */ diff --git a/src/ndisc/nm-ndisc.c b/src/ndisc/nm-ndisc.c index 5e556084e8..8ebf2a16c7 100644 --- a/src/ndisc/nm-ndisc.c +++ b/src/ndisc/nm-ndisc.c @@ -16,6 +16,7 @@ #include "nm-utils.h" #include "platform/nm-platform.h" #include "platform/nmp-netns.h" +#include "nm-l3-config-data.h" #define _NMLOG_PREFIX_NAME "ndisc" @@ -25,6 +26,9 @@ struct _NMNDiscPrivate { /* this *must* be the first field. */ NMNDiscDataInternal rdata; + char *last_error; + GSource *ra_timeout_source; + union { gint32 solicitations_left; gint32 announcements_left; @@ -37,9 +41,7 @@ struct _NMNDiscPrivate { gint32 last_rs; gint32 last_ra; }; - guint ra_timeout_id; /* first RA timeout */ guint timeout_id; /* prefix/dns/etc lifetime timeout */ - char *last_error; NMUtilsIPv6IfaceId iid; /* immutable values: */ @@ -48,7 +50,7 @@ struct _NMNDiscPrivate { char *network_id; NMSettingIP6ConfigAddrGenMode addr_gen_mode; NMUtilsStableType stable_type; - gint32 ra_timeout; + guint32 ra_timeout; gint32 max_addresses; gint32 router_solicitations; gint32 router_solicitation_interval; @@ -92,6 +94,121 @@ static void _config_changed_log (NMNDisc *ndisc, NMNDiscConfigMap changed); /*****************************************************************************/ +NML3ConfigData * +nm_ndisc_data_to_l3cd (NMDedupMultiIndex *multi_idx, + int ifindex, + const NMNDiscData *rdata, + NMSettingIP6ConfigPrivacy ip6_privacy, + guint32 route_table, + guint32 route_metric, + gboolean kernel_support_rta_pref, + gboolean kernel_support_extended_ifa_flags) +{ + nm_auto_unref_l3cd_init NML3ConfigData *l3cd = NULL; + guint32 ifa_flags; + guint8 plen; + guint i; + + l3cd = nm_l3_config_data_new (multi_idx, + ifindex); + + nm_l3_config_data_set_source (l3cd, NM_IP_CONFIG_SOURCE_NDISC); + + nm_l3_config_data_set_ip6_privacy (l3cd, ip6_privacy); + + /* Check, whether kernel is recent enough to help user space handling RA. + * If it's not supported, we have no ipv6-privacy and must add autoconf + * addresses as /128. The reason for the /128 is to prevent the kernel + * from adding a prefix route for this address. */ + ifa_flags = 0; + if (kernel_support_extended_ifa_flags) { + ifa_flags |= IFA_F_NOPREFIXROUTE; + if (NM_IN_SET (ip6_privacy, NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR, + NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR)) + ifa_flags |= IFA_F_MANAGETEMPADDR; + plen = 64; + } else + plen = 128; + + for (i = 0; i < rdata->addresses_n; i++) { + const NMNDiscAddress *ndisc_addr = &rdata->addresses[i]; + NMPlatformIP6Address a; + + a = (NMPlatformIP6Address) { + .ifindex = ifindex, + .address = ndisc_addr->address, + .plen = plen, + .timestamp = ndisc_addr->timestamp, + .lifetime = ndisc_addr->lifetime, + .preferred = MIN (ndisc_addr->lifetime, ndisc_addr->preferred), + .addr_source = NM_IP_CONFIG_SOURCE_NDISC, + .n_ifa_flags = ifa_flags, + }; + + nm_l3_config_data_add_address_6 (l3cd, &a); + } + + for (i = 0; i < rdata->routes_n; i++) { + const NMNDiscRoute *ndisc_route = &rdata->routes[i]; + NMPlatformIP6Route r; + + r = (NMPlatformIP6Route) { + .ifindex = ifindex, + .network = ndisc_route->network, + .plen = ndisc_route->plen, + .gateway = ndisc_route->gateway, + .rt_source = NM_IP_CONFIG_SOURCE_NDISC, + .table_coerced = nm_platform_route_table_coerce (route_table), + .metric = route_metric, + .rt_pref = ndisc_route->preference, + }; + nm_assert ((NMIcmpv6RouterPref) r.rt_pref == ndisc_route->preference); + + nm_l3_config_data_add_route_6 (l3cd, &r); + } + + if (rdata->gateways_n > 0) { + const NMIcmpv6RouterPref first_pref = rdata->gateways[0].preference; + NMPlatformIP6Route r = { + .rt_source = NM_IP_CONFIG_SOURCE_NDISC, + .ifindex = ifindex, + .table_coerced = nm_platform_route_table_coerce (route_table), + .metric = route_metric, + }; + + for (i = 0; i < rdata->gateways_n; i++) { + r.gateway = rdata->gateways[i].address; + r.rt_pref = rdata->gateways[i].preference; + nm_assert ((NMIcmpv6RouterPref) r.rt_pref == rdata->gateways[i].preference); + nm_l3_config_data_add_route_6 (l3cd, &r); + + if ( first_pref != rdata->gateways[i].preference + && !kernel_support_rta_pref) { + /* We are unable to configure a router preference. Hence, we skip all gateways + * with a different preference from the first gateway. Note, that the gateways + * are sorted in order of highest to lowest preference. */ + break; + } + } + } + + for (i = 0; i < rdata->dns_servers_n; i++) + nm_l3_config_data_add_nameserver (l3cd, AF_INET6, &rdata->dns_servers[i].address); + + for (i = 0; i < rdata->dns_domains_n; i++) + nm_l3_config_data_add_search (l3cd, AF_INET6, rdata->dns_domains[i].domain); + + nm_l3_config_data_set_ndisc_hop_limit (l3cd, rdata->hop_limit); + nm_l3_config_data_set_ndisc_reachable_time_msec (l3cd, rdata->reachable_time_ms); + nm_l3_config_data_set_ndisc_retrans_timer_msec (l3cd, rdata->retrans_timer_ms); + + nm_l3_config_data_set_ip6_mtu (l3cd, rdata->mtu); + + return g_steal_pointer (&l3cd); +} + +/*****************************************************************************/ + static guint8 _preference_to_priority (NMIcmpv6RouterPref pref) { @@ -899,7 +1016,7 @@ ndisc_ra_timeout_cb (gpointer user_data) { NMNDisc *ndisc = NM_NDISC (user_data); - NM_NDISC_GET_PRIVATE (ndisc)->ra_timeout_id = 0; + nm_clear_g_source_inst (&NM_NDISC_GET_PRIVATE (ndisc)->ra_timeout_source); g_signal_emit (ndisc, signals[RA_TIMEOUT_SIGNAL], 0); return G_SOURCE_REMOVE; } @@ -915,7 +1032,7 @@ nm_ndisc_start (NMNDisc *ndisc) priv = NM_NDISC_GET_PRIVATE (ndisc); nm_assert (NM_NDISC_GET_CLASS (ndisc)->start); - nm_assert (!priv->ra_timeout_id); + nm_assert (!priv->ra_timeout_source); _LOGD ("starting neighbor discovery for ifindex %d%s", priv->ifindex, @@ -929,27 +1046,83 @@ nm_ndisc_start (NMNDisc *ndisc) NM_NDISC_GET_CLASS (ndisc)->start (ndisc); if (priv->node_type == NM_NDISC_NODE_TYPE_HOST) { - gint32 ra_timeout = priv->ra_timeout; - G_STATIC_ASSERT_EXPR (NM_RA_TIMEOUT_DEFAULT == 0); G_STATIC_ASSERT_EXPR (NM_RA_TIMEOUT_INFINITY == G_MAXINT32); - if (ra_timeout != NM_RA_TIMEOUT_INFINITY) { - if (ra_timeout == NM_RA_TIMEOUT_DEFAULT) { - ra_timeout = NM_MAX ((((gint64) priv->router_solicitations) * priv->router_solicitation_interval) + 1, - 30); - } - nm_assert (ra_timeout > 0 && ra_timeout < NM_RA_TIMEOUT_INFINITY); - _LOGD ("scheduling RA timeout in %d seconds", ra_timeout); - priv->ra_timeout_id = g_timeout_add_seconds (ra_timeout, ndisc_ra_timeout_cb, ndisc); + nm_assert (priv->ra_timeout > 0u); + nm_assert (priv->ra_timeout <= NM_RA_TIMEOUT_INFINITY); + + if (priv->ra_timeout < NM_RA_TIMEOUT_INFINITY) { + guint timeout_msec; + + _LOGD ("scheduling RA timeout in %u seconds", priv->ra_timeout); + if (priv->ra_timeout < G_MAXUINT / 1000u) + timeout_msec = priv->ra_timeout * 1000u; + else + timeout_msec = G_MAXUINT; + priv->ra_timeout_source = nm_g_timeout_source_new (timeout_msec, + G_PRIORITY_DEFAULT, + ndisc_ra_timeout_cb, + ndisc, + NULL); + g_source_attach (priv->ra_timeout_source, NULL); } + solicit_routers (ndisc); return; } + nm_assert (priv->ra_timeout == 0u); nm_assert (priv->node_type == NM_NDISC_NODE_TYPE_ROUTER); announce_router_initial (ndisc); } +void +nm_ndisc_stop (NMNDisc *ndisc) +{ + nm_auto_pop_netns NMPNetns *netns = NULL; + NMNDiscDataInternal *rdata; + NMNDiscPrivate *priv; + + g_return_if_fail (NM_IS_NDISC (ndisc)); + + priv = NM_NDISC_GET_PRIVATE (ndisc); + + nm_assert (NM_NDISC_GET_CLASS (ndisc)->stop); + + _LOGD ("stopping neighbor discovery for ifindex %d", + priv->ifindex); + + if (!nm_ndisc_netns_push (ndisc, &netns)) + return; + + NM_NDISC_GET_CLASS (ndisc)->stop (ndisc); + + rdata = &priv->rdata; + + g_array_set_size (rdata->gateways, 0); + g_array_set_size (rdata->addresses, 0); + g_array_set_size (rdata->routes, 0); + g_array_set_size (rdata->dns_servers, 0); + g_array_set_size (rdata->dns_domains, 0); + priv->rdata.public.hop_limit = 64; + + /* Start at very low number so that last_rs - router_solicitation_interval + * is much lower than nm_utils_get_monotonic_timestamp_sec() at startup. + */ + priv->last_rs = G_MININT32; + nm_clear_g_source_inst (&priv->ra_timeout_source); + nm_clear_g_source (&priv->send_rs_id); + nm_clear_g_source (&priv->send_ra_id); + nm_clear_g_free (&priv->last_error); + nm_clear_g_source (&priv->timeout_id); + + priv->solicitations_left = 0; + priv->announcements_left = 0; + + priv->last_rs = G_MININT32; + priv->last_ra = G_MININT32; +} + NMNDiscConfigMap nm_ndisc_dad_failed (NMNDisc *ndisc, const struct in6_addr *address, gboolean emit_changed_signal) { @@ -1254,7 +1427,7 @@ nm_ndisc_ra_received (NMNDisc *ndisc, gint32 now, NMNDiscConfigMap changed) { NMNDiscPrivate *priv = NM_NDISC_GET_PRIVATE (ndisc); - nm_clear_g_source (&priv->ra_timeout_id); + nm_clear_g_source_inst (&priv->ra_timeout_source); nm_clear_g_source (&priv->send_rs_id); nm_clear_g_free (&priv->last_error); check_timestamps (ndisc, now, changed); @@ -1328,7 +1501,8 @@ set_property (GObject *object, guint prop_id, break; case PROP_RA_TIMEOUT: /* construct-only */ - priv->ra_timeout = g_value_get_int (value); + priv->ra_timeout = g_value_get_uint (value); + nm_assert (priv->ra_timeout <= NM_RA_TIMEOUT_INFINITY); break; case PROP_ROUTER_SOLICITATIONS: /* construct-only */ @@ -1381,7 +1555,7 @@ dispose (GObject *object) NMNDisc *ndisc = NM_NDISC (object); NMNDiscPrivate *priv = NM_NDISC_GET_PRIVATE (ndisc); - nm_clear_g_source (&priv->ra_timeout_id); + nm_clear_g_source_inst (&priv->ra_timeout_source); nm_clear_g_source (&priv->send_rs_id); nm_clear_g_source (&priv->send_ra_id); nm_clear_g_free (&priv->last_error); @@ -1468,11 +1642,11 @@ nm_ndisc_class_init (NMNDiscClass *klass) G_PARAM_STATIC_STRINGS); G_STATIC_ASSERT_EXPR (G_MAXINT32 == NM_RA_TIMEOUT_INFINITY); obj_properties[PROP_RA_TIMEOUT] = - g_param_spec_int (NM_NDISC_RA_TIMEOUT, "", "", - 0, G_MAXINT32, 0, - G_PARAM_WRITABLE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); + g_param_spec_uint (NM_NDISC_RA_TIMEOUT, "", "", + 0, G_MAXINT32, 0, + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); obj_properties[PROP_ROUTER_SOLICITATIONS] = g_param_spec_int (NM_NDISC_ROUTER_SOLICITATIONS, "", "", 1, G_MAXINT32, NM_NDISC_ROUTER_SOLICITATIONS_DEFAULT, diff --git a/src/ndisc/nm-ndisc.h b/src/ndisc/nm-ndisc.h index eeda38e2bf..c074a0a388 100644 --- a/src/ndisc/nm-ndisc.h +++ b/src/ndisc/nm-ndisc.h @@ -16,8 +16,8 @@ #include "platform/nm-platform.h" #include "platform/nmp-object.h" -#define NM_RA_TIMEOUT_DEFAULT ((gint32) 0) -#define NM_RA_TIMEOUT_INFINITY G_MAXINT32 +#define NM_RA_TIMEOUT_DEFAULT ((guint32) 0) +#define NM_RA_TIMEOUT_INFINITY ((guint32) G_MAXINT32) #define NM_TYPE_NDISC (nm_ndisc_get_type ()) #define NM_NDISC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_NDISC, NMNDisc)) @@ -112,15 +112,15 @@ typedef enum { NM_NDISC_NODE_TYPE_ROUTER, } NMNDiscNodeType; -#define NM_NDISC_MAX_ADDRESSES_DEFAULT 16 -#define NM_NDISC_ROUTER_SOLICITATIONS_DEFAULT 3 /* RFC4861 MAX_RTR_SOLICITATIONS */ -#define NM_NDISC_ROUTER_SOLICITATION_INTERVAL_DEFAULT 4 /* RFC4861 RTR_SOLICITATION_INTERVAL */ -#define NM_NDISC_ROUTER_ADVERTISEMENTS_DEFAULT 3 /* RFC4861 MAX_INITIAL_RTR_ADVERTISEMENTS */ -#define NM_NDISC_ROUTER_ADVERT_DELAY 3 /* RFC4861 MIN_DELAY_BETWEEN_RAS */ -#define NM_NDISC_ROUTER_ADVERT_INITIAL_INTERVAL 16 /* RFC4861 MAX_INITIAL_RTR_ADVERT_INTERVAL */ -#define NM_NDISC_ROUTER_ADVERT_DELAY_MS 500 /* RFC4861 MAX_RA_DELAY_TIME */ -#define NM_NDISC_ROUTER_ADVERT_MAX_INTERVAL 600 /* RFC4861 MaxRtrAdvInterval default */ -#define NM_NDISC_ROUTER_LIFETIME 900 /* 1.5 * NM_NDISC_ROUTER_ADVERT_MAX_INTERVAL */ +#define NM_NDISC_MAX_ADDRESSES_DEFAULT 16 +#define NM_NDISC_ROUTER_SOLICITATIONS_DEFAULT 3 /* RFC4861 MAX_RTR_SOLICITATIONS */ +#define NM_NDISC_ROUTER_SOLICITATION_INTERVAL_DEFAULT 4 /* RFC4861 RTR_SOLICITATION_INTERVAL */ +#define NM_NDISC_ROUTER_ADVERTISEMENTS_DEFAULT 3 /* RFC4861 MAX_INITIAL_RTR_ADVERTISEMENTS */ +#define NM_NDISC_ROUTER_ADVERT_DELAY 3 /* RFC4861 MIN_DELAY_BETWEEN_RAS */ +#define NM_NDISC_ROUTER_ADVERT_INITIAL_INTERVAL 16 /* RFC4861 MAX_INITIAL_RTR_ADVERT_INTERVAL */ +#define NM_NDISC_ROUTER_ADVERT_DELAY_MS 500 /* RFC4861 MAX_RA_DELAY_TIME */ +#define NM_NDISC_ROUTER_ADVERT_MAX_INTERVAL 600 /* RFC4861 MaxRtrAdvInterval default */ +#define NM_NDISC_ROUTER_LIFETIME 900 /* 1.5 * NM_NDISC_ROUTER_ADVERT_MAX_INTERVAL */ struct _NMNDiscPrivate; struct _NMNDiscDataInternal; @@ -163,6 +163,7 @@ typedef struct { GObjectClass parent; void (*start) (NMNDisc *ndisc); + void (*stop) (NMNDisc *ndisc); gboolean (*send_rs) (NMNDisc *ndisc, GError **error); gboolean (*send_ra) (NMNDisc *ndisc, GError **error); } NMNDiscClass; @@ -177,6 +178,7 @@ NMNDiscNodeType nm_ndisc_get_node_type (NMNDisc *self); gboolean nm_ndisc_set_iid (NMNDisc *ndisc, const NMUtilsIPv6IfaceId iid); void nm_ndisc_start (NMNDisc *ndisc); +void nm_ndisc_stop (NMNDisc *ndisc); NMNDiscConfigMap nm_ndisc_dad_failed (NMNDisc *ndisc, const struct in6_addr *address, gboolean emit_changed_signal); @@ -217,4 +219,17 @@ nm_ndisc_dad_addr_is_fail_candidate (NMPlatform *platform, return TRUE; } +/*****************************************************************************/ + +struct _NML3ConfigData; + +struct _NML3ConfigData *nm_ndisc_data_to_l3cd (NMDedupMultiIndex *multi_idx, + int ifindex, + const NMNDiscData *rdata, + NMSettingIP6ConfigPrivacy ip6_privacy, + guint32 route_table, + guint32 route_metric, + gboolean kernel_support_rta_pref, + gboolean kernel_support_extended_ifa_flags); + #endif /* __NETWORKMANAGER_NDISC_H__ */ diff --git a/src/ndisc/tests/test-ndisc-linux.c b/src/ndisc/tests/test-ndisc-linux.c index a25478e8d1..87ae3129d6 100644 --- a/src/ndisc/tests/test-ndisc-linux.c +++ b/src/ndisc/tests/test-ndisc-linux.c @@ -25,6 +25,10 @@ main (int argc, char **argv) const char *ifname; NMUtilsIPv6IfaceId iid = { }; GError *error = NULL; + int max_addresses; + int router_solicitations; + int router_solicitation_interval; + guint32 ra_timeout; nmtst_init_with_logging (&argc, &argv, NULL, "DEFAULT"); @@ -45,6 +49,13 @@ main (int argc, char **argv) return EXIT_FAILURE; } + nm_lndp_ndisc_get_sysctl (NM_PLATFORM_GET, + ifname, + &max_addresses, + &router_solicitations, + &router_solicitation_interval, + &ra_timeout); + ndisc = nm_lndp_ndisc_new (NM_PLATFORM_GET, ifindex, ifname, @@ -52,7 +63,10 @@ main (int argc, char **argv) "8ce666e8-d34d-4fb1-b858-f15a7al28086", NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64, NM_NDISC_NODE_TYPE_HOST, - 0, + max_addresses, + router_solicitations, + router_solicitation_interval, + ra_timeout, &error); if (!ndisc) { g_print ("Failed to create NMNDisc instance: %s\n", error->message); diff --git a/src/nm-dbus-utils.c b/src/nm-dbus-utils.c index 07fa909d20..49878cf78e 100644 --- a/src/nm-dbus-utils.c +++ b/src/nm-dbus-utils.c @@ -72,21 +72,35 @@ nm_dbus_utils_get_property (GObject *obj, const char *signature, const char *property_name) { - GParamSpec *pspec; nm_auto_unset_gvalue GValue value = G_VALUE_INIT; + GParamSpec *pspec; + GVariant *variant; nm_assert (G_IS_OBJECT (obj)); nm_assert (g_variant_type_string_is_valid (signature)); nm_assert (property_name && property_name[0]); pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (obj), property_name); - if (!pspec) - g_return_val_if_reached (NULL); + + nm_assert (pspec); + + nm_assert ( pspec->value_type != G_TYPE_VARIANT + || nm_streq ((char *) (((GParamSpecVariant *) pspec)->type), signature)); g_value_init (&value, pspec->value_type); + g_object_get_property (obj, property_name, &value); + + variant = g_dbus_gvalue_to_gvariant (&value, G_VARIANT_TYPE (signature)); + + nm_assert ( !variant + || g_variant_is_of_type (variant, G_VARIANT_TYPE (signature))); + /* returns never-floating variant */ - return g_dbus_gvalue_to_gvariant (&value, G_VARIANT_TYPE (signature)); + nm_assert ( !variant + || !g_variant_is_floating (variant)); + + return variant; } /*****************************************************************************/ diff --git a/src/nm-iface-helper.c b/src/nm-iface-helper.c index 0335b7617a..eb5a4478f3 100644 --- a/src/nm-iface-helper.c +++ b/src/nm-iface-helper.c @@ -552,6 +552,10 @@ main (int argc, char *argv[]) if (global_opt.slaac) { NMUtilsStableType stable_type = NM_UTILS_STABLE_TYPE_UUID; const char *stable_id = global_opt.uuid; + int router_solicitation_interval; + int router_solicitations; + guint32 default_ra_timeout; + int max_addresses; nm_platform_link_set_user_ipv6ll_enabled (NM_PLATFORM_GET, gl.ifindex, TRUE); @@ -564,6 +568,14 @@ main (int argc, char *argv[]) stable_type = (global_opt.stable_id[0] - '0'); stable_id = &global_opt.stable_id[2]; } + + nm_lndp_ndisc_get_sysctl (NM_PLATFORM_GET, + global_opt.ifname, + &max_addresses, + &router_solicitations, + &router_solicitation_interval, + &default_ra_timeout); + ndisc = nm_lndp_ndisc_new (NM_PLATFORM_GET, gl.ifindex, global_opt.ifname, @@ -571,7 +583,10 @@ main (int argc, char *argv[]) stable_id, global_opt.addr_gen_mode, NM_NDISC_NODE_TYPE_HOST, - NM_RA_TIMEOUT_DEFAULT, + max_addresses, + router_solicitations, + router_solicitation_interval, + default_ra_timeout, NULL); g_assert (ndisc); diff --git a/src/nm-l3-config-data.c b/src/nm-l3-config-data.c index bff22c578f..c13fdbc249 100644 --- a/src/nm-l3-config-data.c +++ b/src/nm-l3-config-data.c @@ -119,16 +119,27 @@ struct _NML3ConfigData { NMIPConfigSource source; + int ndisc_hop_limit_val; + guint32 mtu; + guint32 ip6_mtu; + guint32 ndisc_reachable_time_msec_val; + guint32 ndisc_retrans_timer_msec_val; NMTernary metered:3; + NMSettingIP6ConfigPrivacy ip6_privacy:4; + bool is_sealed:1; bool has_routes_with_type_local_4_set:1; bool has_routes_with_type_local_6_set:1; bool has_routes_with_type_local_4_val:1; bool has_routes_with_type_local_6_val:1; + + bool ndisc_hop_limit_set:1; + bool ndisc_reachable_time_msec_set:1; + bool ndisc_retrans_timer_msec_set:1; }; /*****************************************************************************/ @@ -396,16 +407,20 @@ nm_l3_config_data_new (NMDedupMultiIndex *multi_idx, self = g_slice_new (NML3ConfigData); *self = (NML3ConfigData) { - .ref_count = 1, - .ifindex = ifindex, - .multi_idx = nm_dedup_multi_index_ref (multi_idx), - .mdns = NM_SETTING_CONNECTION_MDNS_DEFAULT, - .llmnr = NM_SETTING_CONNECTION_LLMNR_DEFAULT, - .flags = NM_L3_CONFIG_DAT_FLAGS_NONE, - .metered = NM_TERNARY_DEFAULT, - .route_table_sync_4 = NM_IP_ROUTE_TABLE_SYNC_MODE_NONE, - .route_table_sync_6 = NM_IP_ROUTE_TABLE_SYNC_MODE_NONE, - .source = NM_IP_CONFIG_SOURCE_UNKNOWN, + .ref_count = 1, + .ifindex = ifindex, + .multi_idx = nm_dedup_multi_index_ref (multi_idx), + .mdns = NM_SETTING_CONNECTION_MDNS_DEFAULT, + .llmnr = NM_SETTING_CONNECTION_LLMNR_DEFAULT, + .flags = NM_L3_CONFIG_DAT_FLAGS_NONE, + .metered = NM_TERNARY_DEFAULT, + .route_table_sync_4 = NM_IP_ROUTE_TABLE_SYNC_MODE_NONE, + .route_table_sync_6 = NM_IP_ROUTE_TABLE_SYNC_MODE_NONE, + .source = NM_IP_CONFIG_SOURCE_UNKNOWN, + .ip6_privacy = NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN, + .ndisc_hop_limit_set = FALSE, + .ndisc_reachable_time_msec_set = FALSE, + .ndisc_retrans_timer_msec_set = FALSE, }; _idx_type_init (&self->idx_addresses_4, NMP_OBJECT_TYPE_IP4_ADDRESS); @@ -1084,8 +1099,8 @@ nm_l3_config_data_add_nameserver (NML3ConfigData *self, } gboolean -nm_l3_config_data_clear_nameserver (NML3ConfigData *self, - int addr_family) +nm_l3_config_data_clear_nameservers (NML3ConfigData *self, + int addr_family) { gs_unref_array GArray *old = NULL; @@ -1183,6 +1198,19 @@ nm_l3_config_data_add_search (NML3ConfigData *self, } gboolean +nm_l3_config_data_clear_searches (NML3ConfigData *self, + int addr_family) +{ + gs_unref_ptrarray GPtrArray *old = NULL; + + nm_assert (_NM_IS_L3_CONFIG_DATA (self, FALSE)); + nm_assert_addr_family (addr_family); + + old = g_steal_pointer (&self->searches_x[NM_IS_IPv4 (addr_family)]); + return (nm_g_ptr_array_len (old) > 0); +} + +gboolean nm_l3_config_data_add_dns_option (NML3ConfigData *self, int addr_family, const char *dns_option) @@ -1322,6 +1350,27 @@ nm_l3_config_data_set_mtu (NML3ConfigData *self, return TRUE; } +guint32 +nm_l3_config_data_get_ip6_mtu (const NML3ConfigData *self) +{ + nm_assert (_NM_IS_L3_CONFIG_DATA (self, TRUE)); + + return self->ip6_mtu; +} + +gboolean +nm_l3_config_data_set_ip6_mtu (NML3ConfigData *self, + guint32 ip6_mtu) +{ + nm_assert (_NM_IS_L3_CONFIG_DATA (self, FALSE)); + + if (self->ip6_mtu == ip6_mtu) + return FALSE; + + self->ip6_mtu = ip6_mtu; + return TRUE; +} + gboolean nm_l3_config_data_set_source (NML3ConfigData *self, NMIPConfigSource source) @@ -1335,6 +1384,109 @@ nm_l3_config_data_set_source (NML3ConfigData *self, return TRUE; } +NMSettingIP6ConfigPrivacy +nm_l3_config_data_get_ip6_privacy (const NML3ConfigData *self) +{ + nm_assert (_NM_IS_L3_CONFIG_DATA (self, FALSE)); + + return self->ip6_privacy; +} + +gboolean +nm_l3_config_data_set_ip6_privacy (NML3ConfigData *self, + NMSettingIP6ConfigPrivacy ip6_privacy) +{ + nm_assert (_NM_IS_L3_CONFIG_DATA (self, FALSE)); + nm_assert (NM_IN_SET (ip6_privacy, NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN, + NM_SETTING_IP6_CONFIG_PRIVACY_DISABLED, + NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR, + NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR)); + + if (self->ip6_privacy == ip6_privacy) + return FALSE; + self->ip6_privacy = ip6_privacy; + nm_assert (self->ip6_privacy == ip6_privacy); + return TRUE; +} + +gboolean +nm_l3_config_data_get_ndisc_hop_limit (const NML3ConfigData *self, + int *out_val) +{ + nm_assert (_NM_IS_L3_CONFIG_DATA (self, FALSE)); + + if (!self->ndisc_hop_limit_set) { + NM_SET_OUT (out_val, 0); + return FALSE; + } + NM_SET_OUT (out_val, self->ndisc_hop_limit_val); + return TRUE; +} + +gboolean +nm_l3_config_data_set_ndisc_hop_limit (NML3ConfigData *self, + int val) +{ + if ( self->ndisc_hop_limit_set + && self->ndisc_hop_limit_val == val) + return FALSE; + self->ndisc_hop_limit_set = TRUE; + self->ndisc_hop_limit_val = val; + return TRUE; +} + +gboolean +nm_l3_config_data_get_ndisc_reachable_time_msec (const NML3ConfigData *self, + guint32 *out_val) +{ + nm_assert (_NM_IS_L3_CONFIG_DATA (self, FALSE)); + + if (!self->ndisc_reachable_time_msec_set) { + NM_SET_OUT (out_val, 0); + return FALSE; + } + NM_SET_OUT (out_val, self->ndisc_reachable_time_msec_val); + return TRUE; +} + +gboolean +nm_l3_config_data_set_ndisc_reachable_time_msec (NML3ConfigData *self, + guint32 val) +{ + if ( self->ndisc_reachable_time_msec_set + && self->ndisc_reachable_time_msec_val == val) + return FALSE; + self->ndisc_reachable_time_msec_set = TRUE; + self->ndisc_reachable_time_msec_val = val; + return TRUE; +} + +gboolean +nm_l3_config_data_get_ndisc_retrans_timer_msec (const NML3ConfigData *self, + guint32 *out_val) +{ + nm_assert (_NM_IS_L3_CONFIG_DATA (self, FALSE)); + + if (!self->ndisc_retrans_timer_msec_set) { + NM_SET_OUT (out_val, 0); + return FALSE; + } + NM_SET_OUT (out_val, self->ndisc_retrans_timer_msec_val); + return TRUE; +} + +gboolean +nm_l3_config_data_set_ndisc_retrans_timer_msec (NML3ConfigData *self, + guint32 val) +{ + if ( self->ndisc_retrans_timer_msec_set + && self->ndisc_retrans_timer_msec_val == val) + return FALSE; + self->ndisc_retrans_timer_msec_set = TRUE; + self->ndisc_retrans_timer_msec_val = val; + return TRUE; +} + /*****************************************************************************/ NMDhcpLease * @@ -1479,7 +1631,21 @@ nm_l3_config_data_cmp (const NML3ConfigData *a, const NML3ConfigData *b) NM_CMP_DIRECT (a->mdns, b->mdns); NM_CMP_DIRECT (a->llmnr, b->llmnr); NM_CMP_DIRECT (a->mtu, b->mtu); + NM_CMP_DIRECT (a->ip6_mtu, b->ip6_mtu); NM_CMP_DIRECT_UNSAFE (a->metered, b->metered); + NM_CMP_DIRECT_UNSAFE (a->ip6_privacy, b->ip6_privacy); + + NM_CMP_DIRECT_UNSAFE (a->ndisc_hop_limit_set, b->ndisc_hop_limit_set); + if (a->ndisc_hop_limit_set) + NM_CMP_DIRECT (a->ndisc_hop_limit_val, b->ndisc_hop_limit_val); + + NM_CMP_DIRECT_UNSAFE (a->ndisc_reachable_time_msec_set, b->ndisc_reachable_time_msec_set); + if (a->ndisc_reachable_time_msec_set) + NM_CMP_DIRECT (a->ndisc_reachable_time_msec_val, b->ndisc_reachable_time_msec_val); + + NM_CMP_DIRECT_UNSAFE (a->ndisc_retrans_timer_msec_set, b->ndisc_retrans_timer_msec_set); + if (a->ndisc_retrans_timer_msec_set) + NM_CMP_DIRECT (a->ndisc_retrans_timer_msec_val, b->ndisc_retrans_timer_msec_val); NM_CMP_FIELD (a, b, source); @@ -2250,9 +2416,30 @@ nm_l3_config_data_merge (NML3ConfigData *self, if (self->metered == NM_TERNARY_DEFAULT) self->metered = src->metered; - if (self->mtu != 0u) + if (self->ip6_privacy == NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN) + self->ip6_privacy = src->ip6_privacy; + + if (!self->ndisc_hop_limit_set) { + self->ndisc_hop_limit_set = TRUE; + self->ndisc_hop_limit_val = src->ndisc_hop_limit_val; + } + + if (!self->ndisc_reachable_time_msec_set) { + self->ndisc_reachable_time_msec_set = TRUE; + self->ndisc_reachable_time_msec_val = src->ndisc_reachable_time_msec_val; + } + + if (!self->ndisc_retrans_timer_msec_set) { + self->ndisc_retrans_timer_msec_set = TRUE; + self->ndisc_retrans_timer_msec_val = src->ndisc_retrans_timer_msec_val; + } + + if (self->mtu == 0u) self->mtu = src->mtu; + if (self->ip6_mtu == 0u) + self->ip6_mtu = src->ip6_mtu; + /* self->source does not get merged. */ /* self->dhcp_lease_x does not get merged. */ } diff --git a/src/nm-l3-config-data.h b/src/nm-l3-config-data.h index 2a29fad0df..fe7bac03be 100644 --- a/src/nm-l3-config-data.h +++ b/src/nm-l3-config-data.h @@ -439,6 +439,11 @@ guint32 nm_l3_config_data_get_mtu (const NML3ConfigData *self); gboolean nm_l3_config_data_set_mtu (NML3ConfigData *self, guint32 mtu); +guint32 nm_l3_config_data_get_ip6_mtu (const NML3ConfigData *self); + +gboolean nm_l3_config_data_set_ip6_mtu (NML3ConfigData *self, + guint32 ip6_mtu); + const in_addr_t *nm_l3_config_data_get_wins (const NML3ConfigData *self, guint *out_len); @@ -453,8 +458,8 @@ gboolean nm_l3_config_data_add_nameserver (NML3ConfigData *self, int addr_family, gconstpointer /* (const NMIPAddr *) */ nameserver); -gboolean nm_l3_config_data_clear_nameserver (NML3ConfigData *self, - int addr_family); +gboolean nm_l3_config_data_clear_nameservers (NML3ConfigData *self, + int addr_family); gboolean nm_l3_config_data_add_nis_server (NML3ConfigData *self, in_addr_t nis_server); @@ -474,6 +479,9 @@ const char *const*nm_l3_config_data_get_searches (const NML3ConfigData *self, int addr_family, guint *out_len); +gboolean nm_l3_config_data_clear_searches (NML3ConfigData *self, + int addr_family); + gboolean nm_l3_config_data_add_search (NML3ConfigData *self, int addr_family, const char *search); @@ -486,6 +494,26 @@ gboolean nm_l3_config_data_set_dns_priority (NML3ConfigData *self, int addr_family, int dns_priority); +NMSettingIP6ConfigPrivacy nm_l3_config_data_get_ip6_privacy (const NML3ConfigData *self); + +gboolean nm_l3_config_data_set_ip6_privacy (NML3ConfigData *self, + NMSettingIP6ConfigPrivacy ip6_privacy); + +gboolean nm_l3_config_data_get_ndisc_hop_limit (const NML3ConfigData *self, + int *out_val); +gboolean nm_l3_config_data_set_ndisc_hop_limit (NML3ConfigData *self, + int val); + +gboolean nm_l3_config_data_get_ndisc_reachable_time_msec (const NML3ConfigData *self, + guint32 *out_val); +gboolean nm_l3_config_data_set_ndisc_reachable_time_msec (NML3ConfigData *self, + guint32 val); + +gboolean nm_l3_config_data_get_ndisc_retrans_timer_msec (const NML3ConfigData *self, + guint32 *out_val); +gboolean nm_l3_config_data_set_ndisc_retrans_timer_msec (NML3ConfigData *self, + guint32 val); + struct _NMDhcpLease *nm_l3_config_data_get_dhcp_lease (const NML3ConfigData *self, int addr_family); diff --git a/src/nm-l3cfg.c b/src/nm-l3cfg.c index 5354a5dbbf..7526897464 100644 --- a/src/nm-l3cfg.c +++ b/src/nm-l3cfg.c @@ -980,7 +980,7 @@ _l3_acd_nacd_event (int fd, n_acd_probe_get_userdata (event->_acd_event_payload.probe, (void **) &acd_data); _LOGT_acd (acd_data, "address %s %s from %s", - (addr_str = nm_utils_inet4_ntop (acd_data->addr, sbuf_addr)), + (addr_str = _nm_utils_inet4_ntop (acd_data->addr, sbuf_addr)), event->event == N_ACD_EVENT_DEFENDED ? "defended" : "conflict detected", @@ -993,7 +993,7 @@ _l3_acd_nacd_event (int fd, _LOGW ("IPv4 address collision detection sees conflict on interface %i%s%s%s for address %s from host %s", self->priv.ifindex, NM_PRINT_FMT_QUOTED (self->priv.pllink, " (", NMP_OBJECT_CAST_LINK (self->priv.pllink)->name, ")", ""), - addr_str ?: nm_utils_inet4_ntop (acd_data->addr, sbuf_addr), + addr_str ?: _nm_utils_inet4_ntop (acd_data->addr, sbuf_addr), sender_str ?: (sender_str = nm_utils_bin2hexstr_full (event->_acd_event_payload.sender, event->_acd_event_payload.n_sender, @@ -2848,6 +2848,11 @@ _platform_commit (NML3Cfg *self, } } + /* FIXME(l3cfg): need to honor and set nm_l3_config_data_get_ip6_privacy(). */ + /* FIXME(l3cfg): need to honor and set nm_l3_config_data_get_ndisc_*(). */ + /* FIXME(l3cfg): need to honor and set nm_l3_config_data_get_ip6_mtu(). */ + /* FIXME(l3cfg): need to honor and set nm_l3_config_data_get_mtu(). */ + nm_platform_ip_address_sync (self->priv.platform, addr_family, self->priv.ifindex, diff --git a/src/nm-manager.c b/src/nm-manager.c index 8e8723349a..9441fa01c7 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -8172,7 +8172,7 @@ static const NMDBusInterfaceInfoExtended interface_info_manager = { NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("ActivatingConnection", "o", NM_MANAGER_ACTIVATING_CONNECTION), NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Startup", "b", NM_MANAGER_STARTUP), NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Version", "s", NM_MANAGER_VERSION), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Capabilities", "u", NM_MANAGER_CAPABILITIES), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Capabilities", "au", NM_MANAGER_CAPABILITIES), NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("State", "u", NM_MANAGER_STATE), NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Connectivity", "u", NM_MANAGER_CONNECTIVITY), NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("ConnectivityCheckAvailable", "b", NM_MANAGER_CONNECTIVITY_CHECK_AVAILABLE), diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index 83e9c1021d..5a842d8778 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -6047,7 +6047,7 @@ nm_platform_ip4_address_to_string (const NMPlatformIP4Address *address, char *bu "", s_address, address->plen, broadcast_address ? " brd " : "", - broadcast_address ? nm_utils_inet4_ntop (broadcast_address, str_broadcast) : "", + broadcast_address ? _nm_utils_inet4_ntop (broadcast_address, str_broadcast) : "", str_lft_p, str_pref_p, str_time_p, |