diff options
| author | Paweł Jan Czochański <[email protected]> | 2023-01-18 10:10:33 +0100 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2023-01-19 14:44:01 +0100 |
| commit | 8f4fae9b36f017a8ab65491ef49b72499a9486dc (patch) | |
| tree | d5bd2b0df691d7602507093426c3ee5a498c8c5f /embassy-net/src/lib.rs | |
| parent | 2eae12b7f1cbe38d850ebf30f23a776323815af6 (diff) | |
Add smoltcp dhcp socket configuration
Diffstat (limited to 'embassy-net/src/lib.rs')
| -rw-r--r-- | embassy-net/src/lib.rs | 72 |
1 files changed, 52 insertions, 20 deletions
diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs index 757d3e27d..c419ec1f9 100644 --- a/embassy-net/src/lib.rs +++ b/embassy-net/src/lib.rs | |||
| @@ -30,6 +30,8 @@ use smoltcp::iface::SocketHandle; | |||
| 30 | use smoltcp::iface::{Interface, InterfaceBuilder, SocketSet, SocketStorage}; | 30 | use smoltcp::iface::{Interface, InterfaceBuilder, SocketSet, SocketStorage}; |
| 31 | #[cfg(feature = "dhcpv4")] | 31 | #[cfg(feature = "dhcpv4")] |
| 32 | use smoltcp::socket::dhcpv4; | 32 | use smoltcp::socket::dhcpv4; |
| 33 | use smoltcp::socket::dhcpv4::RetryConfig; | ||
| 34 | use smoltcp::time::Duration; | ||
| 33 | // smoltcp reexports | 35 | // smoltcp reexports |
| 34 | pub use smoltcp::time::{Duration as SmolDuration, Instant as SmolInstant}; | 36 | pub use smoltcp::time::{Duration as SmolDuration, Instant as SmolInstant}; |
| 35 | #[cfg(feature = "medium-ethernet")] | 37 | #[cfg(feature = "medium-ethernet")] |
| @@ -45,31 +47,53 @@ use crate::device::DriverAdapter; | |||
| 45 | const LOCAL_PORT_MIN: u16 = 1025; | 47 | const LOCAL_PORT_MIN: u16 = 1025; |
| 46 | const LOCAL_PORT_MAX: u16 = 65535; | 48 | const LOCAL_PORT_MAX: u16 = 65535; |
| 47 | 49 | ||
| 48 | pub struct StackResources<const SOCK: usize, const NEIGHBOR: usize> { | 50 | pub struct StackResources<const SOCK: usize> { |
| 49 | addresses: [IpCidr; 5], | ||
| 50 | sockets: [SocketStorage<'static>; SOCK], | 51 | sockets: [SocketStorage<'static>; SOCK], |
| 51 | } | 52 | } |
| 52 | 53 | ||
| 53 | impl<const SOCK: usize, const NEIGHBOR: usize> StackResources<SOCK, NEIGHBOR> { | 54 | impl<const SOCK: usize> StackResources<SOCK> { |
| 54 | pub fn new() -> Self { | 55 | pub fn new() -> Self { |
| 55 | Self { | 56 | Self { |
| 56 | addresses: [IpCidr::new(Ipv4Address::UNSPECIFIED.into(), 32); 5], | ||
| 57 | sockets: [SocketStorage::EMPTY; SOCK], | 57 | sockets: [SocketStorage::EMPTY; SOCK], |
| 58 | } | 58 | } |
| 59 | } | 59 | } |
| 60 | } | 60 | } |
| 61 | 61 | ||
| 62 | #[derive(Debug, Clone, PartialEq, Eq)] | 62 | #[derive(Debug, Clone, PartialEq, Eq)] |
| 63 | pub struct Config { | 63 | pub struct StaticConfig { |
| 64 | pub address: Ipv4Cidr, | 64 | pub address: Ipv4Cidr, |
| 65 | pub gateway: Option<Ipv4Address>, | 65 | pub gateway: Option<Ipv4Address>, |
| 66 | pub dns_servers: Vec<Ipv4Address, 3>, | 66 | pub dns_servers: Vec<Ipv4Address, 3>, |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | pub enum ConfigStrategy { | 69 | #[derive(Debug, Clone, PartialEq, Eq)] |
| 70 | Static(Config), | 70 | pub struct DhcpConfig { |
| 71 | pub max_lease_duration: Option<Duration>, | ||
| 72 | pub retry_config: RetryConfig, | ||
| 73 | /// Ignore NAKs. | ||
| 74 | pub ignore_naks: bool, | ||
| 75 | /// Server port config | ||
| 76 | pub server_port: u16, | ||
| 77 | /// Client port config | ||
| 78 | pub client_port: u16, | ||
| 79 | } | ||
| 80 | |||
| 81 | impl Default for DhcpConfig { | ||
| 82 | fn default() -> Self { | ||
| 83 | Self { | ||
| 84 | max_lease_duration: Default::default(), | ||
| 85 | retry_config: Default::default(), | ||
| 86 | ignore_naks: Default::default(), | ||
| 87 | server_port: smoltcp::wire::DHCP_SERVER_PORT, | ||
| 88 | client_port: smoltcp::wire::DHCP_CLIENT_PORT, | ||
| 89 | } | ||
| 90 | } | ||
| 91 | } | ||
| 92 | |||
| 93 | pub enum Config { | ||
| 94 | Static(StaticConfig), | ||
| 71 | #[cfg(feature = "dhcpv4")] | 95 | #[cfg(feature = "dhcpv4")] |
| 72 | Dhcp, | 96 | Dhcp(DhcpConfig), |
| 73 | } | 97 | } |
| 74 | 98 | ||
| 75 | pub struct Stack<D: Driver> { | 99 | pub struct Stack<D: Driver> { |
| @@ -80,7 +104,7 @@ pub struct Stack<D: Driver> { | |||
| 80 | struct Inner<D: Driver> { | 104 | struct Inner<D: Driver> { |
| 81 | device: D, | 105 | device: D, |
| 82 | link_up: bool, | 106 | link_up: bool, |
| 83 | config: Option<Config>, | 107 | config: Option<StaticConfig>, |
| 84 | #[cfg(feature = "dhcpv4")] | 108 | #[cfg(feature = "dhcpv4")] |
| 85 | dhcp_socket: Option<SocketHandle>, | 109 | dhcp_socket: Option<SocketHandle>, |
| 86 | } | 110 | } |
| @@ -93,17 +117,16 @@ pub(crate) struct SocketStack { | |||
| 93 | } | 117 | } |
| 94 | 118 | ||
| 95 | impl<D: Driver + 'static> Stack<D> { | 119 | impl<D: Driver + 'static> Stack<D> { |
| 96 | pub fn new<const ADDR: usize, const SOCK: usize, const NEIGH: usize>( | 120 | pub fn new<const SOCK: usize>( |
| 97 | mut device: D, | 121 | mut device: D, |
| 98 | config: ConfigStrategy, | 122 | config: Config, |
| 99 | resources: &'static mut StackResources<SOCK, NEIGH>, | 123 | resources: &'static mut StackResources<SOCK>, |
| 100 | random_seed: u64, | 124 | random_seed: u64, |
| 101 | ) -> Self { | 125 | ) -> Self { |
| 102 | #[cfg(feature = "medium-ethernet")] | 126 | #[cfg(feature = "medium-ethernet")] |
| 103 | let medium = device.capabilities().medium; | 127 | let medium = device.capabilities().medium; |
| 104 | 128 | ||
| 105 | let mut b = InterfaceBuilder::new(); | 129 | let mut b = InterfaceBuilder::new(); |
| 106 | b = b.ip_addrs(Vec::<IpCidr, 5>::from_iter(resources.addresses)); | ||
| 107 | b = b.random_seed(random_seed); | 130 | b = b.random_seed(random_seed); |
| 108 | 131 | ||
| 109 | #[cfg(feature = "medium-ethernet")] | 132 | #[cfg(feature = "medium-ethernet")] |
| @@ -136,10 +159,12 @@ impl<D: Driver + 'static> Stack<D> { | |||
| 136 | }; | 159 | }; |
| 137 | 160 | ||
| 138 | match config { | 161 | match config { |
| 139 | ConfigStrategy::Static(config) => inner.apply_config(&mut socket, config), | 162 | Config::Static(config) => inner.apply_config(&mut socket, config), |
| 140 | #[cfg(feature = "dhcpv4")] | 163 | #[cfg(feature = "dhcpv4")] |
| 141 | ConfigStrategy::Dhcp => { | 164 | Config::Dhcp(config) => { |
| 142 | let handle = socket.sockets.add(smoltcp::socket::dhcpv4::Socket::new()); | 165 | let mut dhcp_socket = smoltcp::socket::dhcpv4::Socket::new(); |
| 166 | inner.apply_dhcp_config(&mut dhcp_socket, config); | ||
| 167 | let handle = socket.sockets.add(dhcp_socket); | ||
| 143 | inner.dhcp_socket = Some(handle); | 168 | inner.dhcp_socket = Some(handle); |
| 144 | } | 169 | } |
| 145 | } | 170 | } |
| @@ -170,7 +195,7 @@ impl<D: Driver + 'static> Stack<D> { | |||
| 170 | self.with(|_s, i| i.config.is_some()) | 195 | self.with(|_s, i| i.config.is_some()) |
| 171 | } | 196 | } |
| 172 | 197 | ||
| 173 | pub fn config(&self) -> Option<Config> { | 198 | pub fn config(&self) -> Option<StaticConfig> { |
| 174 | self.with(|_s, i| i.config.clone()) | 199 | self.with(|_s, i| i.config.clone()) |
| 175 | } | 200 | } |
| 176 | 201 | ||
| @@ -185,7 +210,7 @@ impl<D: Driver + 'static> Stack<D> { | |||
| 185 | } | 210 | } |
| 186 | 211 | ||
| 187 | impl SocketStack { | 212 | impl SocketStack { |
| 188 | #[allow(clippy::absurd_extreme_comparisons)] | 213 | #[allow(clippy::absurd_extreme_comparisons, dead_code)] |
| 189 | pub fn get_local_port(&mut self) -> u16 { | 214 | pub fn get_local_port(&mut self) -> u16 { |
| 190 | let res = self.next_local_port; | 215 | let res = self.next_local_port; |
| 191 | self.next_local_port = if res >= LOCAL_PORT_MAX { LOCAL_PORT_MIN } else { res + 1 }; | 216 | self.next_local_port = if res >= LOCAL_PORT_MAX { LOCAL_PORT_MIN } else { res + 1 }; |
| @@ -194,7 +219,7 @@ impl SocketStack { | |||
| 194 | } | 219 | } |
| 195 | 220 | ||
| 196 | impl<D: Driver + 'static> Inner<D> { | 221 | impl<D: Driver + 'static> Inner<D> { |
| 197 | fn apply_config(&mut self, s: &mut SocketStack, config: Config) { | 222 | fn apply_config(&mut self, s: &mut SocketStack, config: StaticConfig) { |
| 198 | #[cfg(feature = "medium-ethernet")] | 223 | #[cfg(feature = "medium-ethernet")] |
| 199 | let medium = self.device.capabilities().medium; | 224 | let medium = self.device.capabilities().medium; |
| 200 | 225 | ||
| @@ -220,6 +245,13 @@ impl<D: Driver + 'static> Inner<D> { | |||
| 220 | self.config = Some(config) | 245 | self.config = Some(config) |
| 221 | } | 246 | } |
| 222 | 247 | ||
| 248 | fn apply_dhcp_config(&self, socket: &mut smoltcp::socket::dhcpv4::Socket, config: DhcpConfig) { | ||
| 249 | socket.set_ignore_naks(config.ignore_naks); | ||
| 250 | socket.set_max_lease_duration(config.max_lease_duration); | ||
| 251 | socket.set_ports(config.server_port, config.client_port); | ||
| 252 | socket.set_retry_config(config.retry_config); | ||
| 253 | } | ||
| 254 | |||
| 223 | #[allow(unused)] // used only with dhcp | 255 | #[allow(unused)] // used only with dhcp |
| 224 | fn unapply_config(&mut self, s: &mut SocketStack) { | 256 | fn unapply_config(&mut self, s: &mut SocketStack) { |
| 225 | #[cfg(feature = "medium-ethernet")] | 257 | #[cfg(feature = "medium-ethernet")] |
| @@ -280,7 +312,7 @@ impl<D: Driver + 'static> Inner<D> { | |||
| 280 | None => {} | 312 | None => {} |
| 281 | Some(dhcpv4::Event::Deconfigured) => self.unapply_config(s), | 313 | Some(dhcpv4::Event::Deconfigured) => self.unapply_config(s), |
| 282 | Some(dhcpv4::Event::Configured(config)) => { | 314 | Some(dhcpv4::Event::Configured(config)) => { |
| 283 | let config = Config { | 315 | let config = StaticConfig { |
| 284 | address: config.address, | 316 | address: config.address, |
| 285 | gateway: config.router, | 317 | gateway: config.router, |
| 286 | dns_servers: config.dns_servers, | 318 | dns_servers: config.dns_servers, |
