l3cfg: merge branch 'th/l3cfg-9'

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/626
This commit is contained in:
Thomas Haller 2020-09-18 15:26:49 +02:00
commit 86f2ea66f5
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
19 changed files with 709 additions and 149 deletions

2
NEWS
View file

@ -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

View file

@ -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"/>

View file

@ -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.

View file

@ -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.

View file

@ -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)
{

View file

@ -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,

View file

@ -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] =

View file

@ -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;
}

View file

@ -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__ */

View file

@ -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,

View file

@ -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__ */

View file

@ -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);

View file

@ -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;
}
/*****************************************************************************/

View file

@ -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);

View file

@ -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;
@ -1182,6 +1197,19 @@ nm_l3_config_data_add_search (NML3ConfigData *self,
return _check_and_add_domain (&self->searches_x[NM_IS_IPv4 (addr_family)], search);
}
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,
@ -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. */
}

View file

@ -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);

View file

@ -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,

View file

@ -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),

View file

@ -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,