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 8 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
 	struct refcnt refcnt;
266
 	struct refcnt refcnt;
267
 	/** Settings block */
267
 	/** Settings block */
268
 	struct settings settings;
268
 	struct settings settings;
269
+	/** Leased address */
270
+	struct in6_addr lease;
269
 	/** Option list */
271
 	/** Option list */
270
 	struct dhcpv6_option_list options;
272
 	struct dhcpv6_option_list options;
271
 };
273
 };
280
 static int dhcpv6_applies ( struct settings *settings __unused,
282
 static int dhcpv6_applies ( struct settings *settings __unused,
281
 			    const struct setting *setting ) {
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
 	const union dhcpv6_any_option *option;
327
 	const union dhcpv6_any_option *option;
301
 	size_t option_len;
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
 	/* Find option */
334
 	/* Find option */
304
 	option = dhcpv6_option ( &dhcpv6set->options, setting->tag );
335
 	option = dhcpv6_option ( &dhcpv6set->options, setting->tag );
305
 	if ( ! option )
336
 	if ( ! option )
322
 /**
353
 /**
323
  * Register DHCPv6 options as network device settings
354
  * Register DHCPv6 options as network device settings
324
  *
355
  *
356
+ * @v lease		DHCPv6 leased address
325
  * @v options		DHCPv6 option list
357
  * @v options		DHCPv6 option list
326
  * @v parent		Parent settings block
358
  * @v parent		Parent settings block
327
  * @ret rc		Return status code
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
 			     struct settings *parent ) {
363
 			     struct settings *parent ) {
331
 	struct dhcpv6_settings *dhcpv6set;
364
 	struct dhcpv6_settings *dhcpv6set;
332
 	void *data;
365
 	void *data;
347
 	memcpy ( data, options->data, len );
380
 	memcpy ( data, options->data, len );
348
 	dhcpv6set->options.data = data;
381
 	dhcpv6set->options.data = data;
349
 	dhcpv6set->options.len = len;
382
 	dhcpv6set->options.len = len;
383
+	memcpy ( &dhcpv6set->lease, lease, sizeof ( dhcpv6set->lease ) );
350
 
384
 
351
 	/* Register settings */
385
 	/* Register settings */
352
 	if ( ( rc = register_settings ( &dhcpv6set->settings, parent,
386
 	if ( ( rc = register_settings ( &dhcpv6set->settings, parent,
848
 		}
882
 		}
849
 	}
883
 	}
850
 
884
 
851
-	/* Transition to next state or complete DHCPv6, as applicable */
885
+	/* Transition to next state, if applicable */
852
 	if ( dhcpv6->state->next ) {
886
 	if ( dhcpv6->state->next ) {
853
-
854
-		/* Transition to next state */
855
 		dhcpv6_set_state ( dhcpv6, dhcpv6->state->next );
887
 		dhcpv6_set_state ( dhcpv6, dhcpv6->state->next );
856
 		rc = 0;
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
  done:
904
  done:
874
 	free_iob ( iobuf );
905
 	free_iob ( iobuf );
875
 	return rc;
906
 	return rc;

Loading…
Cancel
Save