Browse Source

[dhcpv6] Expose IPv6 address setting acquired through DHCPv6

Originally-implemented-by: Hannes Reinecke <hare@suse.de>
Originally-implemented-by: Marin Hannache <git@mareo.fr>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 7 years ago
parent
commit
03d19cf14d
1 changed files with 49 additions and 18 deletions
  1. 49
    18
      src/net/udp/dhcpv6.c

+ 49
- 18
src/net/udp/dhcpv6.c View File

@@ -266,6 +266,8 @@ struct dhcpv6_settings {
266 266
 	struct refcnt refcnt;
267 267
 	/** Settings block */
268 268
 	struct settings settings;
269
+	/** Leased address */
270
+	struct in6_addr lease;
269 271
 	/** Option list */
270 272
 	struct dhcpv6_option_list options;
271 273
 };
@@ -280,7 +282,32 @@ struct dhcpv6_settings {
280 282
 static int dhcpv6_applies ( struct settings *settings __unused,
281 283
 			    const struct setting *setting ) {
282 284
 
283
-	return ( setting->scope == &dhcpv6_scope );
285
+	return ( ( setting->scope == &dhcpv6_scope ) ||
286
+		 ( setting_cmp ( setting, &ip6_setting ) == 0 ) );
287
+}
288
+
289
+/**
290
+ * Fetch value of DHCPv6 leased address
291
+ *
292
+ * @v dhcpset		DHCPv6 settings
293
+ * @v data		Buffer to fill with setting data
294
+ * @v len		Length of buffer
295
+ * @ret len		Length of setting data, or negative error
296
+ */
297
+static int dhcpv6_fetch_lease ( struct dhcpv6_settings *dhcpv6set,
298
+				void *data, size_t len ) {
299
+	struct in6_addr *lease = &dhcpv6set->lease;
300
+
301
+	/* Do nothing unless a leased address exists */
302
+	if ( IN6_IS_ADDR_UNSPECIFIED ( lease ) )
303
+		return -ENOENT;
304
+
305
+	/* Copy leased address */
306
+	if ( len > sizeof ( *lease ) )
307
+		len = sizeof ( *lease );
308
+	memcpy ( data, lease, len );
309
+
310
+	return sizeof ( *lease );
284 311
 }
285 312
 
286 313
 /**
@@ -300,6 +327,10 @@ static int dhcpv6_fetch ( struct settings *settings,
300 327
 	const union dhcpv6_any_option *option;
301 328
 	size_t option_len;
302 329
 
330
+	/* Handle leased address */
331
+	if ( setting_cmp ( setting, &ip6_setting ) == 0 )
332
+		return dhcpv6_fetch_lease ( dhcpv6set, data, len );
333
+
303 334
 	/* Find option */
304 335
 	option = dhcpv6_option ( &dhcpv6set->options, setting->tag );
305 336
 	if ( ! option )
@@ -322,11 +353,13 @@ static struct settings_operations dhcpv6_settings_operations = {
322 353
 /**
323 354
  * Register DHCPv6 options as network device settings
324 355
  *
356
+ * @v lease		DHCPv6 leased address
325 357
  * @v options		DHCPv6 option list
326 358
  * @v parent		Parent settings block
327 359
  * @ret rc		Return status code
328 360
  */
329
-static int dhcpv6_register ( struct dhcpv6_option_list *options,
361
+static int dhcpv6_register ( struct in6_addr *lease,
362
+			     struct dhcpv6_option_list *options,
330 363
 			     struct settings *parent ) {
331 364
 	struct dhcpv6_settings *dhcpv6set;
332 365
 	void *data;
@@ -347,6 +380,7 @@ static int dhcpv6_register ( struct dhcpv6_option_list *options,
347 380
 	memcpy ( data, options->data, len );
348 381
 	dhcpv6set->options.data = data;
349 382
 	dhcpv6set->options.len = len;
383
+	memcpy ( &dhcpv6set->lease, lease, sizeof ( dhcpv6set->lease ) );
350 384
 
351 385
 	/* Register settings */
352 386
 	if ( ( rc = register_settings ( &dhcpv6set->settings, parent,
@@ -848,28 +882,25 @@ static int dhcpv6_rx ( struct dhcpv6_session *dhcpv6,
848 882
 		}
849 883
 	}
850 884
 
851
-	/* Transition to next state or complete DHCPv6, as applicable */
885
+	/* Transition to next state, if applicable */
852 886
 	if ( dhcpv6->state->next ) {
853
-
854
-		/* Transition to next state */
855 887
 		dhcpv6_set_state ( dhcpv6, dhcpv6->state->next );
856 888
 		rc = 0;
889
+		goto done;
890
+	}
857 891
 
858
-	} else {
859
-
860
-		/* Register settings */
861
-		if ( ( rc = dhcpv6_register ( &options, parent ) ) != 0 ) {
862
-			DBGC ( dhcpv6, "DHCPv6 %s could not register "
863
-			       "settings: %s\n", dhcpv6->netdev->name,
864
-			       strerror ( rc ) );
865
-			goto done;
866
-		}
867
-
868
-		/* Mark as complete */
869
-		dhcpv6_finished ( dhcpv6, 0 );
870
-		DBGC ( dhcpv6, "DHCPv6 %s complete\n", dhcpv6->netdev->name );
892
+	/* Register settings */
893
+	if ( ( rc = dhcpv6_register ( &dhcpv6->lease, &options,
894
+				      parent ) ) != 0 ) {
895
+		DBGC ( dhcpv6, "DHCPv6 %s could not register settings: %s\n",
896
+		       dhcpv6->netdev->name, strerror ( rc ) );
897
+		goto done;
871 898
 	}
872 899
 
900
+	/* Mark as complete */
901
+	dhcpv6_finished ( dhcpv6, 0 );
902
+	DBGC ( dhcpv6, "DHCPv6 %s complete\n", dhcpv6->netdev->name );
903
+
873 904
  done:
874 905
 	free_iob ( iobuf );
875 906
 	return rc;

Loading…
Cancel
Save