summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2020-09-18 15:26:49 +0200
committerThomas Haller <thaller@redhat.com>2020-09-18 15:26:49 +0200
commit86f2ea66f55562722cab7a49fd76021b38dac988 (patch)
treec87e440b2ef19d2767184b2005827b6b33fae938
parent026389fc1f14ed7a121a89f409e919582b88af5b (diff)
parent5e841433786ad6b2de7fe4cf8f6432ca6f925d71 (diff)
downloadNetworkManager-86f2ea66f55562722cab7a49fd76021b38dac988.tar.gz
l3cfg: merge branch 'th/l3cfg-9'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/626
-rw-r--r--NEWS2
-rw-r--r--introspection/org.freedesktop.NetworkManager.Device.xml2
-rw-r--r--libnm-core/nm-utils.c12
-rw-r--r--shared/nm-glib-aux/nm-shared-utils.c28
-rw-r--r--shared/nm-glib-aux/nm-shared-utils.h2
-rw-r--r--src/devices/nm-device.c96
-rw-r--r--src/ndisc/nm-fake-ndisc.c15
-rw-r--r--src/ndisc/nm-lndp-ndisc.c119
-rw-r--r--src/ndisc/nm-lndp-ndisc.h12
-rw-r--r--src/ndisc/nm-ndisc.c220
-rw-r--r--src/ndisc/nm-ndisc.h37
-rw-r--r--src/ndisc/tests/test-ndisc-linux.c16
-rw-r--r--src/nm-dbus-utils.c22
-rw-r--r--src/nm-iface-helper.c17
-rw-r--r--src/nm-l3-config-data.c213
-rw-r--r--src/nm-l3-config-data.h32
-rw-r--r--src/nm-l3cfg.c9
-rw-r--r--src/nm-manager.c2
-rw-r--r--src/platform/nm-platform.c2
19 files changed, 709 insertions, 149 deletions
diff --git a/NEWS b/NEWS
index a9a0ea12f9..4b00eeba53 100644
--- a/NEWS
+++ b/NEWS
@@ -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,