@@ -38,8 +38,15 @@ use super::fragmentation::{Fragmenter, FragmentsBuffer};
3838#[ cfg( any( feature = "medium-ethernet" , feature = "medium-ieee802154" ) ) ]
3939use super :: neighbor:: { Answer as NeighborAnswer , Cache as NeighborCache } ;
4040use super :: socket_set:: SocketSet ;
41- use crate :: config:: { IFACE_MAX_ADDR_COUNT , IFACE_MAX_SIXLOWPAN_ADDRESS_CONTEXT_COUNT } ;
41+ use crate :: config:: {
42+ IFACE_MAX_ADDR_COUNT , IFACE_MAX_PREFIX_COUNT , IFACE_MAX_SIXLOWPAN_ADDRESS_CONTEXT_COUNT ,
43+ } ;
4244use crate :: iface:: Routes ;
45+ #[ cfg( all(
46+ feature = "proto-ipv6" ,
47+ any( feature = "medium-ethernet" , feature = "medium-ieee802154" )
48+ ) ) ]
49+ use crate :: iface:: Slaac ;
4350use crate :: phy:: PacketMeta ;
4451use crate :: phy:: { ChecksumCapabilities , Device , DeviceCapabilities , Medium , RxToken , TxToken } ;
4552use crate :: rand:: Rand ;
@@ -142,6 +149,16 @@ pub struct InterfaceInner {
142149 tag : u16 ,
143150 ip_addrs : Vec < IpCidr , IFACE_MAX_ADDR_COUNT > ,
144151 any_ip : bool ,
152+ #[ cfg( all(
153+ feature = "proto-ipv6" ,
154+ any( feature = "medium-ethernet" , feature = "medium-ieee802154" )
155+ ) ) ]
156+ slaac_enabled : bool ,
157+ #[ cfg( all(
158+ feature = "proto-ipv6" ,
159+ any( feature = "medium-ethernet" , feature = "medium-ieee802154" )
160+ ) ) ]
161+ slaac : Slaac ,
145162 routes : Routes ,
146163 #[ cfg( feature = "multicast" ) ]
147164 multicast : multicast:: State ,
@@ -169,6 +186,10 @@ pub struct Config {
169186 /// **NOTE**: we use the same PAN ID for destination and source.
170187 #[ cfg( feature = "medium-ieee802154" ) ]
171188 pub pan_id : Option < Ieee802154Pan > ,
189+
190+ /// Enable stateless address autoconfiguration on the interface.
191+ #[ cfg( feature = "proto-ipv6" ) ]
192+ pub slaac : bool ,
172193}
173194
174195impl Config {
@@ -178,6 +199,8 @@ impl Config {
178199 hardware_addr,
179200 #[ cfg( feature = "medium-ieee802154" ) ]
180201 pan_id : None ,
202+ #[ cfg( feature = "proto-ipv6" ) ]
203+ slaac : false ,
181204 }
182205 }
183206}
@@ -262,6 +285,16 @@ impl Interface {
262285 ipv4_id,
263286 #[ cfg( feature = "proto-sixlowpan" ) ]
264287 sixlowpan_address_context : Vec :: new ( ) ,
288+ #[ cfg( all(
289+ feature = "proto-ipv6" ,
290+ any( feature = "medium-ethernet" , feature = "medium-ieee802154" )
291+ ) ) ]
292+ slaac_enabled : config. slaac ,
293+ #[ cfg( all(
294+ feature = "proto-ipv6" ,
295+ any( feature = "medium-ethernet" , feature = "medium-ieee802154" )
296+ ) ) ]
297+ slaac : Slaac :: new ( ) ,
265298 rand,
266299 } ,
267300 }
@@ -491,6 +524,14 @@ impl Interface {
491524 }
492525 }
493526
527+ #[ cfg( all(
528+ feature = "proto-ipv6" ,
529+ any( feature = "medium-ethernet" , feature = "medium-ieee802154" )
530+ ) ) ]
531+ if self . inner . slaac_enabled {
532+ self . ndisc_rs_egress ( device) ;
533+ }
534+
494535 #[ cfg( feature = "multicast" ) ]
495536 self . multicast_egress ( device) ;
496537
@@ -526,6 +567,14 @@ impl Interface {
526567
527568 #[ cfg( feature = "_proto-fragmentation" ) ]
528569 self . fragments . assembler . remove_expired ( timestamp) ;
570+
571+ #[ cfg( all(
572+ feature = "proto-ipv6" ,
573+ any( feature = "medium-ethernet" , feature = "medium-ieee802154" )
574+ ) ) ]
575+ if self . inner . slaac . sync_required ( timestamp) {
576+ self . sync_slaac_state ( timestamp)
577+ }
529578 }
530579
531580 /// Return a _soft deadline_ for calling [poll] the next time.
@@ -546,6 +595,15 @@ impl Interface {
546595
547596 let inner = & mut self . inner ;
548597
598+ let other_polls = [
599+ #[ cfg( all(
600+ feature = "proto-ipv6" ,
601+ any( feature = "medium-ethernet" , feature = "medium-ieee802154" )
602+ ) ) ]
603+ inner. slaac . poll_at ( timestamp) ,
604+ None ,
605+ ] ;
606+
549607 sockets
550608 . items ( )
551609 . filter_map ( move |item| {
@@ -559,6 +617,7 @@ impl Interface {
559617 PollAt :: Now => Some ( Instant :: from_millis ( 0 ) ) ,
560618 }
561619 } )
620+ . chain ( other_polls. into_iter ( ) . flatten ( ) )
562621 . min ( )
563622 }
564623
0 commit comments