summary refs log tree commit diff
path: root/src/ndisc
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2020-02-19 23:31:24 +0100
committerMichael Biebl <biebl@debian.org>2020-02-19 23:31:24 +0100
commite536d40eaea5dcdc0743b0a5e8e17faa46608a50 (patch)
tree0749832d8655215dac973866b4e724f3aea35448 /src/ndisc
parentf3c6d0765dff885e168b94f28e06ecc640315a74 (diff)
New upstream version 1.22.8 upstream/1.22.8
Diffstat (limited to 'src/ndisc')
-rw-r--r--src/ndisc/nm-lndp-ndisc.c2
-rw-r--r--src/ndisc/nm-lndp-ndisc.h1
-rw-r--r--src/ndisc/nm-ndisc.c77
-rw-r--r--src/ndisc/nm-ndisc.h8
-rw-r--r--src/ndisc/tests/test-ndisc-linux.c1
5 files changed, 62 insertions, 27 deletions
diff --git a/src/ndisc/nm-lndp-ndisc.c b/src/ndisc/nm-lndp-ndisc.c
index 8077099f..6f2815ef 100644
--- a/src/ndisc/nm-lndp-ndisc.c
+++ b/src/ndisc/nm-lndp-ndisc.c
@@ -557,6 +557,7 @@ nm_lndp_ndisc_new (NMPlatform *platform,
                    const char *network_id,
                    NMSettingIP6ConfigAddrGenMode addr_gen_mode,
                    NMNDiscNodeType node_type,
+                   gint32 ra_timeout,
                    GError **error)
 {
 	nm_auto_pop_netns NMPNetns *netns = NULL;
@@ -582,6 +583,7 @@ nm_lndp_ndisc_new (NMPlatform *platform,
 	                      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),
diff --git a/src/ndisc/nm-lndp-ndisc.h b/src/ndisc/nm-lndp-ndisc.h
index 22f21e41..82e7b2de 100644
--- a/src/ndisc/nm-lndp-ndisc.h
+++ b/src/ndisc/nm-lndp-ndisc.h
@@ -28,6 +28,7 @@ NMNDisc *nm_lndp_ndisc_new (NMPlatform *platform,
                             const char *network_id,
                             NMSettingIP6ConfigAddrGenMode addr_gen_mode,
                             NMNDiscNodeType node_type,
+                            gint32 ra_timeout,
                             GError **error);
 
 #endif /* __NETWORKMANAGER_LNDP_NDISC_H__ */
diff --git a/src/ndisc/nm-ndisc.c b/src/ndisc/nm-ndisc.c
index 8dda03a7..0afca26b 100644
--- a/src/ndisc/nm-ndisc.c
+++ b/src/ndisc/nm-ndisc.c
@@ -48,6 +48,7 @@ struct _NMNDiscPrivate {
 	char *network_id;
 	NMSettingIP6ConfigAddrGenMode addr_gen_mode;
 	NMUtilsStableType stable_type;
+	gint32 ra_timeout;
 	gint32 max_addresses;
 	gint32 router_solicitations;
 	gint32 router_solicitation_interval;
@@ -67,6 +68,7 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE (
 	PROP_NETWORK_ID,
 	PROP_ADDR_GEN_MODE,
 	PROP_MAX_ADDRESSES,
+	PROP_RA_TIMEOUT,
 	PROP_ROUTER_SOLICITATIONS,
 	PROP_ROUTER_SOLICITATION_INTERVAL,
 	PROP_NODE_TYPE,
@@ -74,7 +76,7 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE (
 
 enum {
 	CONFIG_RECEIVED,
-	RA_TIMEOUT,
+	RA_TIMEOUT_SIGNAL,
 	LAST_SIGNAL
 };
 
@@ -898,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;
-	g_signal_emit (ndisc, signals[RA_TIMEOUT], 0);
+	g_signal_emit (ndisc, signals[RA_TIMEOUT_SIGNAL], 0);
 	return G_SOURCE_REMOVE;
 }
 
@@ -906,34 +908,46 @@ void
 nm_ndisc_start (NMNDisc *ndisc)
 {
 	nm_auto_pop_netns NMPNetns *netns = NULL;
-	NMNDiscPrivate *priv = NM_NDISC_GET_PRIVATE (ndisc);
-	NMNDiscClass *klass = NM_NDISC_GET_CLASS (ndisc);
-	gint64 ra_wait_secs;
+	NMNDiscPrivate *priv;
+
+	g_return_if_fail (NM_IS_NDISC (ndisc));
+
+	priv = NM_NDISC_GET_PRIVATE (ndisc);
 
-	g_return_if_fail (klass->start);
-	g_return_if_fail (!priv->ra_timeout_id);
+	nm_assert (NM_NDISC_GET_CLASS (ndisc)->start);
+	nm_assert (!priv->ra_timeout_id);
 
-	_LOGD ("starting neighbor discovery: %d", priv->ifindex);
+	_LOGD ("starting neighbor discovery for ifindex %d%s",
+	       priv->ifindex,
+	         priv->node_type == NM_NDISC_NODE_TYPE_HOST
+	       ? " (solicit)"
+	       : " (announce)");
 
 	if (!nm_ndisc_netns_push (ndisc, &netns))
 		return;
 
-	klass->start (ndisc);
+	NM_NDISC_GET_CLASS (ndisc)->start (ndisc);
+
+	if (priv->node_type == NM_NDISC_NODE_TYPE_HOST) {
+		gint32 ra_timeout = priv->ra_timeout;
 
-	switch (priv->node_type) {
-	case NM_NDISC_NODE_TYPE_HOST:
-		ra_wait_secs = (((gint64) priv->router_solicitations) * priv->router_solicitation_interval) + 1;
-		ra_wait_secs = MAX (ra_wait_secs, 30);
-		priv->ra_timeout_id = g_timeout_add_seconds (ra_wait_secs, ndisc_ra_timeout_cb, ndisc);
-		_LOGD ("scheduling RA timeout in %d seconds", (int) ra_wait_secs);
+		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);
+		}
 		solicit_routers (ndisc);
-		break;
-	case NM_NDISC_NODE_TYPE_ROUTER:
-		announce_router_initial (ndisc);
-		break;
-	default:
-		g_assert_not_reached ();
+		return;
 	}
+
+	nm_assert (priv->node_type == NM_NDISC_NODE_TYPE_ROUTER);
+	announce_router_initial (ndisc);
 }
 
 NMNDiscConfigMap
@@ -1312,6 +1326,10 @@ set_property (GObject *object, guint prop_id,
 		/* construct-only */
 		priv->max_addresses = g_value_get_int (value);
 		break;
+	case PROP_RA_TIMEOUT:
+		/* construct-only */
+		priv->ra_timeout = g_value_get_int (value);
+		break;
 	case PROP_ROUTER_SOLICITATIONS:
 		/* construct-only */
 		priv->router_solicitations = g_value_get_int (value);
@@ -1323,6 +1341,8 @@ set_property (GObject *object, guint prop_id,
 	case PROP_NODE_TYPE:
 		/* construct-only */
 		priv->node_type = g_value_get_int (value);
+		nm_assert (NM_IN_SET (priv->node_type, NM_NDISC_NODE_TYPE_HOST,
+		                                       NM_NDISC_NODE_TYPE_ROUTER));
 		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -1401,8 +1421,8 @@ nm_ndisc_class_init (NMNDiscClass *klass)
 	g_type_class_add_private (klass, sizeof (NMNDiscPrivate));
 
 	object_class->set_property = set_property;
-	object_class->dispose = dispose;
-	object_class->finalize = finalize;
+	object_class->dispose      = dispose;
+	object_class->finalize     = finalize;
 
 	obj_properties[PROP_PLATFORM] =
 	    g_param_spec_object (NM_NDISC_PLATFORM, "", "",
@@ -1446,6 +1466,13 @@ nm_ndisc_class_init (NMNDiscClass *klass)
 	                      G_PARAM_WRITABLE |
 	                      G_PARAM_CONSTRUCT_ONLY |
 	                      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);
 	obj_properties[PROP_ROUTER_SOLICITATIONS] =
 	    g_param_spec_int (NM_NDISC_ROUTER_SOLICITATIONS, "", "",
 	                      1, G_MAXINT32, NM_NDISC_ROUTER_SOLICITATIONS_DEFAULT,
@@ -1473,8 +1500,8 @@ nm_ndisc_class_init (NMNDiscClass *klass)
 	                  0,
 	                  NULL, NULL, NULL,
 	                  G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_UINT);
-	signals[RA_TIMEOUT] =
-	    g_signal_new (NM_NDISC_RA_TIMEOUT,
+	signals[RA_TIMEOUT_SIGNAL] =
+	    g_signal_new (NM_NDISC_RA_TIMEOUT_SIGNAL,
 	                  G_OBJECT_CLASS_TYPE (klass),
 	                  G_SIGNAL_RUN_FIRST,
 	                  0,
diff --git a/src/ndisc/nm-ndisc.h b/src/ndisc/nm-ndisc.h
index 92295ac6..eeda38e2 100644
--- a/src/ndisc/nm-ndisc.h
+++ b/src/ndisc/nm-ndisc.h
@@ -16,6 +16,9 @@
 #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_TYPE_NDISC            (nm_ndisc_get_type ())
 #define NM_NDISC(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_NDISC, NMNDisc))
 #define NM_NDISC_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_NDISC, NMNDiscClass))
@@ -31,11 +34,12 @@
 #define NM_NDISC_STABLE_TYPE    "stable-type"
 #define NM_NDISC_NODE_TYPE      "node-type"
 #define NM_NDISC_MAX_ADDRESSES  "max-addresses"
+#define NM_NDISC_RA_TIMEOUT     "ra-timeout"
 #define NM_NDISC_ROUTER_SOLICITATIONS "router-solicitations"
 #define NM_NDISC_ROUTER_SOLICITATION_INTERVAL "router-solicitation-interval"
 
-#define NM_NDISC_CONFIG_RECEIVED "config-received"
-#define NM_NDISC_RA_TIMEOUT      "ra-timeout"
+#define NM_NDISC_CONFIG_RECEIVED   "config-received"
+#define NM_NDISC_RA_TIMEOUT_SIGNAL "ra-timeout-signal"
 
 typedef enum {
 	NM_NDISC_DHCP_LEVEL_UNKNOWN,
diff --git a/src/ndisc/tests/test-ndisc-linux.c b/src/ndisc/tests/test-ndisc-linux.c
index e9ceaa2b..a25478e8 100644
--- a/src/ndisc/tests/test-ndisc-linux.c
+++ b/src/ndisc/tests/test-ndisc-linux.c
@@ -52,6 +52,7 @@ main (int argc, char **argv)
 	                           "8ce666e8-d34d-4fb1-b858-f15a7al28086",
 	                           NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64,
 	                           NM_NDISC_NODE_TYPE_HOST,
+	                           0,
 	                           &error);
 	if (!ndisc) {
 		g_print ("Failed to create NMNDisc instance: %s\n", error->message);