diff options
| author | Ruben De Smet <[email protected]> | 2023-06-05 16:12:24 +0200 |
|---|---|---|
| committer | Ruben De Smet <[email protected]> | 2023-06-06 17:58:45 +0200 |
| commit | d7f674e410a674f06a749859bde4081a99718f58 (patch) | |
| tree | fde6f73d9534bc12477443845b3ec9a1cde047de | |
| parent | e871324bde25bd61241aed83416caf6e49376d5a (diff) | |
net: Allow setting an IPv6 in the stack
| -rw-r--r-- | embassy-net/src/lib.rs | 72 |
1 files changed, 68 insertions, 4 deletions
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 { | |||
| 80 | pub dns_servers: Vec<Ipv4Address, 3>, | 80 | pub dns_servers: Vec<Ipv4Address, 3>, |
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | /// Static IPv6 address configuration | ||
| 84 | #[cfg(feature = "proto-ipv6")] | ||
| 85 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
| 86 | pub struct StaticConfigV6 { | ||
| 87 | /// IP address and subnet mask. | ||
| 88 | pub address: Ipv6Cidr, | ||
| 89 | /// Default gateway. | ||
| 90 | pub gateway: Option<Ipv6Address>, | ||
| 91 | /// DNS servers. | ||
| 92 | pub dns_servers: Vec<Ipv6Address, 3>, | ||
| 93 | } | ||
| 94 | |||
| 83 | /// DHCP configuration. | 95 | /// DHCP configuration. |
| 84 | #[cfg(feature = "dhcpv4")] | 96 | #[cfg(feature = "dhcpv4")] |
| 85 | #[derive(Debug, Clone, PartialEq, Eq)] | 97 | #[derive(Debug, Clone, PartialEq, Eq)] |
| @@ -116,9 +128,12 @@ impl Default for DhcpConfig { | |||
| 116 | 128 | ||
| 117 | /// Network stack configuration. | 129 | /// Network stack configuration. |
| 118 | pub enum Config { | 130 | pub enum Config { |
| 119 | /// Use a static IP address configuration. | 131 | /// Use a static IPv4 address configuration. |
| 120 | #[cfg(feature = "proto-ipv4")] | 132 | #[cfg(feature = "proto-ipv4")] |
| 121 | StaticV4(StaticConfigV4), | 133 | StaticV4(StaticConfigV4), |
| 134 | /// Use a static IPv6 address configuration. | ||
| 135 | #[cfg(feature = "proto-ipv6")] | ||
| 136 | StaticV6(StaticConfigV6), | ||
| 122 | /// Use DHCP to obtain an IP address configuration. | 137 | /// Use DHCP to obtain an IP address configuration. |
| 123 | #[cfg(feature = "dhcpv4")] | 138 | #[cfg(feature = "dhcpv4")] |
| 124 | Dhcp(DhcpConfig), | 139 | Dhcp(DhcpConfig), |
| @@ -137,6 +152,8 @@ struct Inner<D: Driver> { | |||
| 137 | link_up: bool, | 152 | link_up: bool, |
| 138 | #[cfg(feature = "proto-ipv4")] | 153 | #[cfg(feature = "proto-ipv4")] |
| 139 | static_v4: Option<StaticConfigV4>, | 154 | static_v4: Option<StaticConfigV4>, |
| 155 | #[cfg(feature = "proto-ipv6")] | ||
| 156 | static_v6: Option<StaticConfigV6>, | ||
| 140 | #[cfg(feature = "dhcpv4")] | 157 | #[cfg(feature = "dhcpv4")] |
| 141 | dhcp_socket: Option<SocketHandle>, | 158 | dhcp_socket: Option<SocketHandle>, |
| 142 | #[cfg(feature = "dns")] | 159 | #[cfg(feature = "dns")] |
| @@ -194,6 +211,8 @@ impl<D: Driver + 'static> Stack<D> { | |||
| 194 | link_up: false, | 211 | link_up: false, |
| 195 | #[cfg(feature = "proto-ipv4")] | 212 | #[cfg(feature = "proto-ipv4")] |
| 196 | static_v4: None, | 213 | static_v4: None, |
| 214 | #[cfg(feature = "proto-ipv6")] | ||
| 215 | static_v6: None, | ||
| 197 | #[cfg(feature = "dhcpv4")] | 216 | #[cfg(feature = "dhcpv4")] |
| 198 | dhcp_socket: None, | 217 | dhcp_socket: None, |
| 199 | #[cfg(feature = "dns")] | 218 | #[cfg(feature = "dns")] |
| @@ -208,7 +227,11 @@ impl<D: Driver + 'static> Stack<D> { | |||
| 208 | match config { | 227 | match config { |
| 209 | #[cfg(feature = "proto-ipv4")] | 228 | #[cfg(feature = "proto-ipv4")] |
| 210 | Config::StaticV4(config) => { | 229 | Config::StaticV4(config) => { |
| 211 | inner.apply_config(&mut socket, config); | 230 | inner.apply_config_v4(&mut socket, config); |
| 231 | } | ||
| 232 | #[cfg(feature = "proto-ipv6")] | ||
| 233 | Config::StaticV6(config) => { | ||
| 234 | inner.apply_config_v6(&mut socket, config); | ||
| 212 | } | 235 | } |
| 213 | #[cfg(feature = "dhcpv4")] | 236 | #[cfg(feature = "dhcpv4")] |
| 214 | Config::Dhcp(config) => { | 237 | Config::Dhcp(config) => { |
| @@ -392,7 +415,7 @@ impl SocketStack { | |||
| 392 | 415 | ||
| 393 | impl<D: Driver + 'static> Inner<D> { | 416 | impl<D: Driver + 'static> Inner<D> { |
| 394 | #[cfg(feature = "proto-ipv4")] | 417 | #[cfg(feature = "proto-ipv4")] |
| 395 | fn apply_config(&mut self, s: &mut SocketStack, config: StaticConfigV4) { | 418 | fn apply_config_v4(&mut self, s: &mut SocketStack, config: StaticConfigV4) { |
| 396 | #[cfg(feature = "medium-ethernet")] | 419 | #[cfg(feature = "medium-ethernet")] |
| 397 | let medium = self.device.capabilities().medium; | 420 | let medium = self.device.capabilities().medium; |
| 398 | 421 | ||
| @@ -431,6 +454,47 @@ impl<D: Driver + 'static> Inner<D> { | |||
| 431 | self.static_v4 = Some(config) | 454 | self.static_v4 = Some(config) |
| 432 | } | 455 | } |
| 433 | 456 | ||
| 457 | /// Replaces the current IPv6 static configuration with a newly supplied config. | ||
| 458 | #[cfg(feature = "proto-ipv6")] | ||
| 459 | fn apply_config_v6(&mut self, s: &mut SocketStack, config: StaticConfigV6) { | ||
| 460 | #[cfg(feature = "medium-ethernet")] | ||
| 461 | let medium = self.device.capabilities().medium; | ||
| 462 | |||
| 463 | debug!("Acquired IPv6 configuration:"); | ||
| 464 | |||
| 465 | debug!(" IP address: {}", config.address); | ||
| 466 | s.iface.update_ip_addrs(|addrs| { | ||
| 467 | if addrs.is_empty() { | ||
| 468 | addrs.push(IpCidr::Ipv6(config.address)).unwrap(); | ||
| 469 | } else { | ||
| 470 | addrs[0] = IpCidr::Ipv6(config.address); | ||
| 471 | } | ||
| 472 | }); | ||
| 473 | |||
| 474 | #[cfg(feature = "medium-ethernet")] | ||
| 475 | if Medium::Ethernet == medium { | ||
| 476 | if let Some(gateway) = config.gateway { | ||
| 477 | debug!(" Default gateway: {}", gateway); | ||
| 478 | s.iface.routes_mut().add_default_ipv6_route(gateway).unwrap(); | ||
| 479 | } else { | ||
| 480 | debug!(" Default gateway: None"); | ||
| 481 | s.iface.routes_mut().remove_default_ipv6_route(); | ||
| 482 | } | ||
| 483 | } | ||
| 484 | for (i, s) in config.dns_servers.iter().enumerate() { | ||
| 485 | debug!(" DNS server {}: {}", i, s); | ||
| 486 | } | ||
| 487 | |||
| 488 | #[cfg(feature = "dns")] | ||
| 489 | { | ||
| 490 | let socket = s.sockets.get_mut::<smoltcp::socket::dns::Socket>(self.dns_socket); | ||
| 491 | let servers: Vec<IpAddress, 3> = config.dns_servers.iter().map(|c| IpAddress::Ipv6(*c)).collect(); | ||
| 492 | socket.update_servers(&servers[..]); | ||
| 493 | } | ||
| 494 | |||
| 495 | self.static_v6 = Some(config) | ||
| 496 | } | ||
| 497 | |||
| 434 | #[cfg(feature = "dhcpv4")] | 498 | #[cfg(feature = "dhcpv4")] |
| 435 | fn apply_dhcp_config(&self, socket: &mut smoltcp::socket::dhcpv4::Socket, config: DhcpConfig) { | 499 | fn apply_dhcp_config(&self, socket: &mut smoltcp::socket::dhcpv4::Socket, config: DhcpConfig) { |
| 436 | socket.set_ignore_naks(config.ignore_naks); | 500 | socket.set_ignore_naks(config.ignore_naks); |
| @@ -499,7 +563,7 @@ impl<D: Driver + 'static> Inner<D> { | |||
| 499 | gateway: config.router, | 563 | gateway: config.router, |
| 500 | dns_servers: config.dns_servers, | 564 | dns_servers: config.dns_servers, |
| 501 | }; | 565 | }; |
| 502 | self.apply_config(s, config) | 566 | self.apply_config_v4(s, config) |
| 503 | } | 567 | } |
| 504 | } | 568 | } |
| 505 | } else if old_link_up { | 569 | } else if old_link_up { |
