From 54bab33c7342510be538bc6d8545fe50146557cf Mon Sep 17 00:00:00 2001 From: Ruben De Smet Date: Mon, 5 Jun 2023 14:57:17 +0200 Subject: Rename StaticConfig to StaticConfigV4 --- embassy-net/src/lib.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'embassy-net/src/lib.rs') diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs index bccbad521..ddb325c6c 100644 --- a/embassy-net/src/lib.rs +++ b/embassy-net/src/lib.rs @@ -68,7 +68,7 @@ impl StackResources { /// Static IP address configuration. #[derive(Debug, Clone, PartialEq, Eq)] -pub struct StaticConfig { +pub struct StaticConfigV4 { /// IP address and subnet mask. pub address: Ipv4Cidr, /// Default gateway. @@ -114,7 +114,7 @@ impl Default for DhcpConfig { /// Network stack configuration. pub enum Config { /// Use a static IP address configuration. - Static(StaticConfig), + Static(StaticConfigV4), /// Use DHCP to obtain an IP address configuration. #[cfg(feature = "dhcpv4")] Dhcp(DhcpConfig), @@ -131,7 +131,7 @@ pub struct Stack { struct Inner { device: D, link_up: bool, - config: Option, + config: Option, #[cfg(feature = "dhcpv4")] dhcp_socket: Option, #[cfg(feature = "dns")] @@ -243,7 +243,7 @@ impl Stack { } /// Get the current IP configuration. - pub fn config(&self) -> Option { + pub fn config(&self) -> Option { self.with(|_s, i| i.config.clone()) } @@ -374,7 +374,7 @@ impl SocketStack { } impl Inner { - fn apply_config(&mut self, s: &mut SocketStack, config: StaticConfig) { + fn apply_config(&mut self, s: &mut SocketStack, config: StaticConfigV4) { #[cfg(feature = "medium-ethernet")] let medium = self.device.capabilities().medium; @@ -470,7 +470,7 @@ impl Inner { None => {} Some(dhcpv4::Event::Deconfigured) => self.unapply_config(s), Some(dhcpv4::Event::Configured(config)) => { - let config = StaticConfig { + let config = StaticConfigV4 { address: config.address, gateway: config.router, dns_servers: config.dns_servers, -- cgit From e871324bde25bd61241aed83416caf6e49376d5a Mon Sep 17 00:00:00 2001 From: Ruben De Smet Date: Mon, 5 Jun 2023 16:00:53 +0200 Subject: net: StaticV4 config behind proto-ipv4 --- embassy-net/src/lib.rs | 46 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 11 deletions(-) (limited to 'embassy-net/src/lib.rs') diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs index ddb325c6c..2e713cd10 100644 --- a/embassy-net/src/lib.rs +++ b/embassy-net/src/lib.rs @@ -34,7 +34,9 @@ use smoltcp::socket::dhcpv4::{self, RetryConfig}; pub use smoltcp::wire::IpListenEndpoint; #[cfg(feature = "medium-ethernet")] pub use smoltcp::wire::{EthernetAddress, HardwareAddress}; -pub use smoltcp::wire::{IpAddress, IpCidr, Ipv4Address, Ipv4Cidr}; +pub use smoltcp::wire::{IpAddress, IpCidr}; +#[cfg(feature = "proto-ipv4")] +pub use smoltcp::wire::{Ipv4Address, Ipv4Cidr}; #[cfg(feature = "proto-ipv6")] pub use smoltcp::wire::{Ipv6Address, Ipv6Cidr}; @@ -67,6 +69,7 @@ impl StackResources { } /// Static IP address configuration. +#[cfg(feature = "proto-ipv4")] #[derive(Debug, Clone, PartialEq, Eq)] pub struct StaticConfigV4 { /// IP address and subnet mask. @@ -114,7 +117,8 @@ impl Default for DhcpConfig { /// Network stack configuration. pub enum Config { /// Use a static IP address configuration. - Static(StaticConfigV4), + #[cfg(feature = "proto-ipv4")] + StaticV4(StaticConfigV4), /// Use DHCP to obtain an IP address configuration. #[cfg(feature = "dhcpv4")] Dhcp(DhcpConfig), @@ -131,7 +135,8 @@ pub struct Stack { struct Inner { device: D, link_up: bool, - config: Option, + #[cfg(feature = "proto-ipv4")] + static_v4: Option, #[cfg(feature = "dhcpv4")] dhcp_socket: Option, #[cfg(feature = "dns")] @@ -187,7 +192,8 @@ impl Stack { let mut inner = Inner { device, link_up: false, - config: None, + #[cfg(feature = "proto-ipv4")] + static_v4: None, #[cfg(feature = "dhcpv4")] dhcp_socket: None, #[cfg(feature = "dns")] @@ -200,7 +206,8 @@ impl Stack { }; match config { - Config::Static(config) => { + #[cfg(feature = "proto-ipv4")] + Config::StaticV4(config) => { inner.apply_config(&mut socket, config); } #[cfg(feature = "dhcpv4")] @@ -239,12 +246,21 @@ impl Stack { /// Get whether the network stack has a valid IP configuration. /// This is true if the network stack has a static IP configuration or if DHCP has completed pub fn is_config_up(&self) -> bool { - self.with(|_s, i| i.config.is_some()) + #[cfg(feature = "proto-ipv4")] + { + return self.config_v4().is_some(); + } + + #[cfg(not(any(feature = "proto-ipv4")))] + { + false + } } /// Get the current IP configuration. - pub fn config(&self) -> Option { - self.with(|_s, i| i.config.clone()) + #[cfg(feature = "proto-ipv4")] + pub fn config_v4(&self) -> Option { + self.with(|_s, i| i.static_v4.clone()) } /// Run the network stack. @@ -264,6 +280,7 @@ impl Stack { pub async fn dns_query(&self, name: &str, qtype: dns::DnsQueryType) -> Result, dns::Error> { // For A and AAAA queries we try detect whether `name` is just an IP address match qtype { + #[cfg(feature = "proto-ipv4")] dns::DnsQueryType::A => { if let Ok(ip) = name.parse().map(IpAddress::Ipv4) { return Ok([ip].into_iter().collect()); @@ -374,6 +391,7 @@ impl SocketStack { } impl Inner { + #[cfg(feature = "proto-ipv4")] fn apply_config(&mut self, s: &mut SocketStack, config: StaticConfigV4) { #[cfg(feature = "medium-ethernet")] let medium = self.device.capabilities().medium; @@ -410,7 +428,7 @@ impl Inner { socket.update_servers(&servers[..]); } - self.config = Some(config) + self.static_v4 = Some(config) } #[cfg(feature = "dhcpv4")] @@ -430,9 +448,15 @@ impl Inner { s.iface.update_ip_addrs(|ip_addrs| ip_addrs.clear()); #[cfg(feature = "medium-ethernet")] if medium == Medium::Ethernet { - s.iface.routes_mut().remove_default_ipv4_route(); + #[cfg(feature = "proto-ipv4")] + { + s.iface.routes_mut().remove_default_ipv4_route(); + } + } + #[cfg(feature = "proto-ipv4")] + { + self.static_v4 = None } - self.config = None } fn poll(&mut self, cx: &mut Context<'_>, s: &mut SocketStack) { -- cgit From d7f674e410a674f06a749859bde4081a99718f58 Mon Sep 17 00:00:00 2001 From: Ruben De Smet Date: Mon, 5 Jun 2023 16:12:24 +0200 Subject: net: Allow setting an IPv6 in the stack --- embassy-net/src/lib.rs | 72 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 68 insertions(+), 4 deletions(-) (limited to 'embassy-net/src/lib.rs') diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs index 2e713cd10..9f83cb4ea 100644 --- a/embassy-net/src/lib.rs +++ b/embassy-net/src/lib.rs @@ -80,6 +80,18 @@ pub struct StaticConfigV4 { pub dns_servers: Vec, } +/// Static IPv6 address configuration +#[cfg(feature = "proto-ipv6")] +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct StaticConfigV6 { + /// IP address and subnet mask. + pub address: Ipv6Cidr, + /// Default gateway. + pub gateway: Option, + /// DNS servers. + pub dns_servers: Vec, +} + /// DHCP configuration. #[cfg(feature = "dhcpv4")] #[derive(Debug, Clone, PartialEq, Eq)] @@ -116,9 +128,12 @@ impl Default for DhcpConfig { /// Network stack configuration. pub enum Config { - /// Use a static IP address configuration. + /// Use a static IPv4 address configuration. #[cfg(feature = "proto-ipv4")] StaticV4(StaticConfigV4), + /// Use a static IPv6 address configuration. + #[cfg(feature = "proto-ipv6")] + StaticV6(StaticConfigV6), /// Use DHCP to obtain an IP address configuration. #[cfg(feature = "dhcpv4")] Dhcp(DhcpConfig), @@ -137,6 +152,8 @@ struct Inner { link_up: bool, #[cfg(feature = "proto-ipv4")] static_v4: Option, + #[cfg(feature = "proto-ipv6")] + static_v6: Option, #[cfg(feature = "dhcpv4")] dhcp_socket: Option, #[cfg(feature = "dns")] @@ -194,6 +211,8 @@ impl Stack { link_up: false, #[cfg(feature = "proto-ipv4")] static_v4: None, + #[cfg(feature = "proto-ipv6")] + static_v6: None, #[cfg(feature = "dhcpv4")] dhcp_socket: None, #[cfg(feature = "dns")] @@ -208,7 +227,11 @@ impl Stack { match config { #[cfg(feature = "proto-ipv4")] Config::StaticV4(config) => { - inner.apply_config(&mut socket, config); + inner.apply_config_v4(&mut socket, config); + } + #[cfg(feature = "proto-ipv6")] + Config::StaticV6(config) => { + inner.apply_config_v6(&mut socket, config); } #[cfg(feature = "dhcpv4")] Config::Dhcp(config) => { @@ -392,7 +415,7 @@ impl SocketStack { impl Inner { #[cfg(feature = "proto-ipv4")] - fn apply_config(&mut self, s: &mut SocketStack, config: StaticConfigV4) { + fn apply_config_v4(&mut self, s: &mut SocketStack, config: StaticConfigV4) { #[cfg(feature = "medium-ethernet")] let medium = self.device.capabilities().medium; @@ -431,6 +454,47 @@ impl Inner { self.static_v4 = Some(config) } + /// Replaces the current IPv6 static configuration with a newly supplied config. + #[cfg(feature = "proto-ipv6")] + fn apply_config_v6(&mut self, s: &mut SocketStack, config: StaticConfigV6) { + #[cfg(feature = "medium-ethernet")] + let medium = self.device.capabilities().medium; + + debug!("Acquired IPv6 configuration:"); + + debug!(" IP address: {}", config.address); + s.iface.update_ip_addrs(|addrs| { + if addrs.is_empty() { + addrs.push(IpCidr::Ipv6(config.address)).unwrap(); + } else { + addrs[0] = IpCidr::Ipv6(config.address); + } + }); + + #[cfg(feature = "medium-ethernet")] + if Medium::Ethernet == medium { + if let Some(gateway) = config.gateway { + debug!(" Default gateway: {}", gateway); + s.iface.routes_mut().add_default_ipv6_route(gateway).unwrap(); + } else { + debug!(" Default gateway: None"); + s.iface.routes_mut().remove_default_ipv6_route(); + } + } + for (i, s) in config.dns_servers.iter().enumerate() { + debug!(" DNS server {}: {}", i, s); + } + + #[cfg(feature = "dns")] + { + let socket = s.sockets.get_mut::(self.dns_socket); + let servers: Vec = config.dns_servers.iter().map(|c| IpAddress::Ipv6(*c)).collect(); + socket.update_servers(&servers[..]); + } + + self.static_v6 = Some(config) + } + #[cfg(feature = "dhcpv4")] fn apply_dhcp_config(&self, socket: &mut smoltcp::socket::dhcpv4::Socket, config: DhcpConfig) { socket.set_ignore_naks(config.ignore_naks); @@ -499,7 +563,7 @@ impl Inner { gateway: config.router, dns_servers: config.dns_servers, }; - self.apply_config(s, config) + self.apply_config_v4(s, config) } } } else if old_link_up { -- cgit From 18578fd15f29e92280e4e317ff3148ea498566dd Mon Sep 17 00:00:00 2001 From: Ruben De Smet Date: Mon, 5 Jun 2023 16:35:31 +0200 Subject: net: Allow a combined use of IPv4 and IPv6 DNS servers --- embassy-net/src/lib.rs | 49 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 9 deletions(-) (limited to 'embassy-net/src/lib.rs') diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs index 9f83cb4ea..23ec33262 100644 --- a/embassy-net/src/lib.rs +++ b/embassy-net/src/lib.rs @@ -444,14 +444,12 @@ impl Inner { debug!(" DNS server {}: {}", i, s); } + self.static_v4 = Some(config); + #[cfg(feature = "dns")] { - let socket = s.sockets.get_mut::(self.dns_socket); - let servers: Vec = config.dns_servers.iter().map(|c| IpAddress::Ipv4(*c)).collect(); - socket.update_servers(&servers[..]); + self.update_dns_servers(s) } - - self.static_v4 = Some(config) } /// Replaces the current IPv6 static configuration with a newly supplied config. @@ -485,14 +483,47 @@ impl Inner { debug!(" DNS server {}: {}", i, s); } + self.static_v6 = Some(config); + #[cfg(feature = "dns")] { - let socket = s.sockets.get_mut::(self.dns_socket); - let servers: Vec = config.dns_servers.iter().map(|c| IpAddress::Ipv6(*c)).collect(); - socket.update_servers(&servers[..]); + self.update_dns_servers(s) + } + } + + #[cfg(feature = "dns")] + fn update_dns_servers(&mut self, s: &mut SocketStack) { + let socket = s.sockets.get_mut::(self.dns_socket); + + let servers_v4; + #[cfg(feature = "proto-ipv4")] + { + servers_v4 = self + .static_v4 + .iter() + .flat_map(|cfg| cfg.dns_servers.iter().map(|c| IpAddress::Ipv4(*c))); + }; + #[cfg(not(feature = "proto-ipv4"))] + { + servers_v4 = core::iter::empty(); + } + + let servers_v6; + #[cfg(feature = "proto-ipv6")] + { + servers_v6 = self + .static_v6 + .iter() + .flat_map(|cfg| cfg.dns_servers.iter().map(|c| IpAddress::Ipv6(*c))); + } + #[cfg(not(feature = "proto-ipv6"))] + { + servers_v6 = core::iter::empty(); } - self.static_v6 = Some(config) + // Prefer the v6 DNS servers over the v4 servers + let servers: Vec = servers_v6.chain(servers_v4).collect(); + socket.update_servers(&servers[..]); } #[cfg(feature = "dhcpv4")] -- cgit From ae1dedc0596832f5ec2389d8ff845b10c0a480f1 Mon Sep 17 00:00:00 2001 From: Ruben De Smet Date: Tue, 6 Jun 2023 11:17:02 +0200 Subject: net: proto-ipv6 in is_config_up --- embassy-net/src/lib.rs | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) (limited to 'embassy-net/src/lib.rs') diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs index 23ec33262..4cc191d44 100644 --- a/embassy-net/src/lib.rs +++ b/embassy-net/src/lib.rs @@ -269,23 +269,42 @@ impl Stack { /// Get whether the network stack has a valid IP configuration. /// This is true if the network stack has a static IP configuration or if DHCP has completed pub fn is_config_up(&self) -> bool { + let v4_up; + let v6_up; + #[cfg(feature = "proto-ipv4")] { - return self.config_v4().is_some(); + v4_up = self.config_v4().is_some(); + } + #[cfg(not(feature = "proto-ipv4"))] + { + v4_up = false; } - #[cfg(not(any(feature = "proto-ipv4")))] + #[cfg(feature = "proto-ipv6")] + { + v6_up = self.config_v6().is_some(); + } + #[cfg(not(feature = "proto-ipv6"))] { - false + v6_up = false; } + + v4_up || v6_up } - /// Get the current IP configuration. + /// Get the current IPv4 configuration. #[cfg(feature = "proto-ipv4")] pub fn config_v4(&self) -> Option { self.with(|_s, i| i.static_v4.clone()) } + /// Get the current IPv6 configuration. + #[cfg(feature = "proto-ipv6")] + pub fn config_v6(&self) -> Option { + self.with(|_s, i| i.static_v6.clone()) + } + /// Run the network stack. /// /// You must call this in a background task, to process network events. -- cgit From 352f0b6c3823797576c36f417d6be40189bca5d5 Mon Sep 17 00:00:00 2001 From: Ruben De Smet Date: Wed, 7 Jun 2023 12:04:15 +0200 Subject: net: Support dual stackĀ IP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- embassy-net/src/lib.rs | 75 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 62 insertions(+), 13 deletions(-) (limited to 'embassy-net/src/lib.rs') diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs index 4cc191d44..cf7ebad3f 100644 --- a/embassy-net/src/lib.rs +++ b/embassy-net/src/lib.rs @@ -127,16 +127,61 @@ impl Default for DhcpConfig { } /// Network stack configuration. -pub enum Config { - /// Use a static IPv4 address configuration. +pub struct Config { #[cfg(feature = "proto-ipv4")] - StaticV4(StaticConfigV4), - /// Use a static IPv6 address configuration. + pub ipv4: ConfigV4, #[cfg(feature = "proto-ipv6")] - StaticV6(StaticConfigV6), + pub ipv6: ConfigV6, +} + +impl Config { + #[cfg(feature = "proto-ipv4")] + pub fn ipv4_static(config: StaticConfigV4) -> Self { + Self { + ipv4: ConfigV4::Static(config), + #[cfg(feature = "proto-ipv6")] + ipv6: ConfigV6::None, + } + } + + #[cfg(feature = "proto-ipv6")] + pub fn ipv6_static(config: StaticConfigV6) -> Self { + Self { + #[cfg(feature = "proto-ipv4")] + ipv4: ConfigV4::None, + ipv6: ConfigV6::Static(config), + } + } + + #[cfg(feature = "dhcpv4")] + pub fn dhcpv4(config: DhcpConfig) -> Self { + Self { + ipv4: ConfigV4::Dhcp(config), + #[cfg(feature = "proto-ipv6")] + ipv6: ConfigV6::None, + } + } +} + +/// Network stack IPv4 configuration. +#[cfg(feature = "proto-ipv4")] +pub enum ConfigV4 { + /// Use a static IPv4 address configuration. + Static(StaticConfigV4), /// Use DHCP to obtain an IP address configuration. #[cfg(feature = "dhcpv4")] Dhcp(DhcpConfig), + /// Do not configure IPv6. + None, +} + +/// Network stack IPv6 configuration. +#[cfg(feature = "proto-ipv6")] +pub enum ConfigV6 { + /// Use a static IPv6 address configuration. + Static(StaticConfigV6), + /// Do not configure IPv6. + None, } /// A network stack. @@ -224,22 +269,26 @@ impl Stack { dns_waker: WakerRegistration::new(), }; - match config { - #[cfg(feature = "proto-ipv4")] - Config::StaticV4(config) => { + #[cfg(feature = "proto-ipv4")] + match config.ipv4 { + ConfigV4::Static(config) => { inner.apply_config_v4(&mut socket, config); } - #[cfg(feature = "proto-ipv6")] - Config::StaticV6(config) => { - inner.apply_config_v6(&mut socket, config); - } #[cfg(feature = "dhcpv4")] - Config::Dhcp(config) => { + ConfigV4::Dhcp(config) => { let mut dhcp_socket = smoltcp::socket::dhcpv4::Socket::new(); inner.apply_dhcp_config(&mut dhcp_socket, config); let handle = socket.sockets.add(dhcp_socket); inner.dhcp_socket = Some(handle); } + ConfigV4::None => {} + } + #[cfg(feature = "proto-ipv6")] + match config.ipv6 { + ConfigV6::Static(config) => { + inner.apply_config_v6(&mut socket, config); + } + ConfigV6::None => {} } Self { -- cgit From 2455fd4dbe4e874a9a200d3026f66d437449b04d Mon Sep 17 00:00:00 2001 From: Ruben De Smet Date: Wed, 7 Jun 2023 12:08:53 +0200 Subject: net: Add documentation to new Config system --- embassy-net/src/lib.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'embassy-net/src/lib.rs') diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs index cf7ebad3f..7e8f765f9 100644 --- a/embassy-net/src/lib.rs +++ b/embassy-net/src/lib.rs @@ -128,13 +128,16 @@ impl Default for DhcpConfig { /// Network stack configuration. pub struct Config { + /// IPv4 configuration #[cfg(feature = "proto-ipv4")] pub ipv4: ConfigV4, + /// IPv6 configuration #[cfg(feature = "proto-ipv6")] pub ipv6: ConfigV6, } impl Config { + /// IPv4 configuration with static addressing. #[cfg(feature = "proto-ipv4")] pub fn ipv4_static(config: StaticConfigV4) -> Self { Self { @@ -144,6 +147,7 @@ impl Config { } } + /// IPv6 configuration with static addressing. #[cfg(feature = "proto-ipv6")] pub fn ipv6_static(config: StaticConfigV6) -> Self { Self { @@ -153,6 +157,12 @@ impl Config { } } + /// IPv6 configuration with dynamic addressing. + /// + /// # Example + /// ```rust + /// let _cfg = Config::dhcpv4(Default::default()); + /// ``` #[cfg(feature = "dhcpv4")] pub fn dhcpv4(config: DhcpConfig) -> Self { Self { -- cgit