|
@@ -35,6 +35,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
35
|
35
|
#include <ipxe/in.h>
|
36
|
36
|
#include <ipxe/crc32.h>
|
37
|
37
|
#include <ipxe/errortab.h>
|
|
38
|
+#include <ipxe/ipv6.h>
|
38
|
39
|
#include <ipxe/dhcpv6.h>
|
39
|
40
|
|
40
|
41
|
/** @file
|
|
@@ -408,16 +409,19 @@ enum dhcpv6_session_state_flags {
|
408
|
409
|
/** Include leased IPv6 address within request */
|
409
|
410
|
DHCPV6_TX_IAADDR = 0x02,
|
410
|
411
|
/** Record received server ID */
|
411
|
|
- DHCPV6_RX_SERVER_ID = 0x04,
|
|
412
|
+ DHCPV6_RX_RECORD_SERVER_ID = 0x04,
|
412
|
413
|
/** Record received IPv6 address */
|
413
|
|
- DHCPV6_RX_IAADDR = 0x08,
|
|
414
|
+ DHCPV6_RX_RECORD_IAADDR = 0x08,
|
|
415
|
+ /** Apply received IPv6 address */
|
|
416
|
+ DHCPV6_RX_APPLY_IAADDR = 0x10,
|
414
|
417
|
};
|
415
|
418
|
|
416
|
419
|
/** DHCPv6 request state */
|
417
|
420
|
static struct dhcpv6_session_state dhcpv6_request = {
|
418
|
421
|
.tx_type = DHCPV6_REQUEST,
|
419
|
422
|
.rx_type = DHCPV6_REPLY,
|
420
|
|
- .flags = ( DHCPV6_TX_IA_NA | DHCPV6_TX_IAADDR | DHCPV6_RX_IAADDR ),
|
|
423
|
+ .flags = ( DHCPV6_TX_IA_NA | DHCPV6_TX_IAADDR |
|
|
424
|
+ DHCPV6_RX_RECORD_IAADDR | DHCPV6_RX_APPLY_IAADDR ),
|
421
|
425
|
.next = NULL,
|
422
|
426
|
};
|
423
|
427
|
|
|
@@ -425,7 +429,8 @@ static struct dhcpv6_session_state dhcpv6_request = {
|
425
|
429
|
static struct dhcpv6_session_state dhcpv6_solicit = {
|
426
|
430
|
.tx_type = DHCPV6_SOLICIT,
|
427
|
431
|
.rx_type = DHCPV6_ADVERTISE,
|
428
|
|
- .flags = ( DHCPV6_TX_IA_NA | DHCPV6_RX_SERVER_ID | DHCPV6_RX_IAADDR ),
|
|
432
|
+ .flags = ( DHCPV6_TX_IA_NA | DHCPV6_RX_RECORD_SERVER_ID |
|
|
433
|
+ DHCPV6_RX_RECORD_IAADDR ),
|
429
|
434
|
.next = &dhcpv6_request,
|
430
|
435
|
};
|
431
|
436
|
|
|
@@ -785,7 +790,7 @@ static int dhcpv6_rx ( struct dhcpv6_session *dhcpv6,
|
785
|
790
|
}
|
786
|
791
|
|
787
|
792
|
/* Record identity association address, if applicable */
|
788
|
|
- if ( dhcpv6->state->flags & DHCPV6_RX_IAADDR ) {
|
|
793
|
+ if ( dhcpv6->state->flags & DHCPV6_RX_RECORD_IAADDR ) {
|
789
|
794
|
if ( ( rc = dhcpv6_iaaddr ( &options, dhcpv6->iaid,
|
790
|
795
|
&dhcpv6->lease ) ) != 0 ) {
|
791
|
796
|
DBGC ( dhcpv6, "DHCPv6 %s received %s with unusable "
|
|
@@ -802,7 +807,7 @@ static int dhcpv6_rx ( struct dhcpv6_session *dhcpv6,
|
802
|
807
|
}
|
803
|
808
|
|
804
|
809
|
/* Record server ID, if applicable */
|
805
|
|
- if ( dhcpv6->state->flags & DHCPV6_RX_SERVER_ID ) {
|
|
810
|
+ if ( dhcpv6->state->flags & DHCPV6_RX_RECORD_SERVER_ID ) {
|
806
|
811
|
assert ( dhcpv6->server_duid == NULL );
|
807
|
812
|
option = dhcpv6_option ( &options, DHCPV6_SERVER_ID );
|
808
|
813
|
if ( ! option ) {
|
|
@@ -822,6 +827,19 @@ static int dhcpv6_rx ( struct dhcpv6_session *dhcpv6,
|
822
|
827
|
dhcpv6->server_duid_len );
|
823
|
828
|
}
|
824
|
829
|
|
|
830
|
+ /* Apply identity association address, if applicable */
|
|
831
|
+ if ( dhcpv6->state->flags & DHCPV6_RX_APPLY_IAADDR ) {
|
|
832
|
+ if ( ( rc = ipv6_set_address ( dhcpv6->netdev,
|
|
833
|
+ &dhcpv6->lease ) ) != 0 ) {
|
|
834
|
+ DBGC ( dhcpv6, "DHCPv6 %s could not apply %s: %s\n",
|
|
835
|
+ dhcpv6->netdev->name,
|
|
836
|
+ inet6_ntoa ( &dhcpv6->lease ), strerror ( rc ) );
|
|
837
|
+ /* This is plausibly the error we want to return */
|
|
838
|
+ dhcpv6->rc = rc;
|
|
839
|
+ goto done;
|
|
840
|
+ }
|
|
841
|
+ }
|
|
842
|
+
|
825
|
843
|
/* Transition to next state or complete DHCPv6, as applicable */
|
826
|
844
|
if ( dhcpv6->state->next ) {
|
827
|
845
|
|