diff options
author | Thomas Haller <thaller@redhat.com> | 2020-09-14 18:49:34 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2020-09-15 15:08:03 +0200 |
commit | e8eaaa78d1dc777bcaf11e20cc93d3509d9aa0b7 (patch) | |
tree | 7d641e83cef7eddea069074f413a17287482a3b1 | |
parent | f6692367b14b024c963452d47edd6a3e0cb3d6bf (diff) | |
download | NetworkManager-e8eaaa78d1dc777bcaf11e20cc93d3509d9aa0b7.tar.gz |
device/ndisc: let calling code determine the used RA timeout for NMNDisc
Previously, if we passed ra_timeout 0 to NMNDisc, then it would
calculate the effective timeout based on the router-solicitations
and the router-solicitation-interval.
The caller may want to know the used timeout, to also run its own timers
with the same timeout. Hence, it cannot leave this automatism internal
to NMNDisc.
-rw-r--r-- | src/devices/nm-device.c | 49 | ||||
-rw-r--r-- | src/ndisc/nm-fake-ndisc.c | 4 | ||||
-rw-r--r-- | src/ndisc/nm-lndp-ndisc.c | 64 | ||||
-rw-r--r-- | src/ndisc/nm-lndp-ndisc.h | 12 | ||||
-rw-r--r-- | src/ndisc/nm-ndisc.c | 57 | ||||
-rw-r--r-- | src/ndisc/nm-ndisc.h | 22 | ||||
-rw-r--r-- | src/ndisc/tests/test-ndisc-linux.c | 16 | ||||
-rw-r--r-- | src/nm-iface-helper.c | 17 |
8 files changed, 179 insertions, 62 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index f0fe5a0385..674d54ebf8 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -1179,7 +1179,7 @@ out_good: return duid_out; } -static gint32 +static guint32 _prop_get_ipv6_ra_timeout (NMDevice *self) { NMConnection *connection; @@ -1191,9 +1191,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 +10981,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 +10990,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 +11009,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 +11037,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); diff --git a/src/ndisc/nm-fake-ndisc.c b/src/ndisc/nm-fake-ndisc.c index 5f4594b983..5e5adfb844 100644 --- a/src/ndisc/nm-fake-ndisc.c +++ b/src/ndisc/nm-fake-ndisc.c @@ -360,6 +360,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); } diff --git a/src/ndisc/nm-lndp-ndisc.c b/src/ndisc/nm-lndp-ndisc.c index 25666c2e45..0d78a5356b 100644 --- a/src/ndisc/nm-lndp-ndisc.c +++ b/src/ndisc/nm-lndp-ndisc.c @@ -550,6 +550,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 +608,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 +634,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); 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..9b2002905c 100644 --- a/src/ndisc/nm-ndisc.c +++ b/src/ndisc/nm-ndisc.c @@ -25,6 +25,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 +40,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 +49,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; @@ -899,7 +900,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 +916,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,23 +930,32 @@ 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); } @@ -1254,7 +1264,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 +1338,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 +1392,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 +1479,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..4130fd9f77 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; 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-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); |