1use net_types::ip::{Ipv4, Ipv4Addr, Ipv6, Ipv6Addr};
8use net_types::SpecifiedAddr;
9use netstack3_base::{IpAddressId, IpDeviceAddr, IpDeviceAddressIdContext};
10
11use crate::internal::device::state::{IpAddressData, IpAddressFlags, IpDeviceStateBindingsTypes};
12use crate::internal::device::{IpDeviceAddressContext as _, IpDeviceIpExt, IpDeviceStateContext};
13use crate::internal::socket::ipv6_source_address_selection::{self, SasCandidate};
14
15pub trait IpSasHandler<I: IpDeviceIpExt, BT>: IpDeviceAddressIdContext<I> {
23 fn get_local_addr_for_remote(
26 &mut self,
27 device_id: &Self::DeviceId,
28 remote: Option<SpecifiedAddr<I::Addr>>,
29 ) -> Option<IpDeviceAddr<I::Addr>> {
30 self.get_local_addr_id_for_remote(device_id, remote).map(|id| id.addr())
31 }
32
33 fn get_local_addr_id_for_remote(
36 &mut self,
37 device_id: &Self::DeviceId,
38 remote: Option<SpecifiedAddr<I::Addr>>,
39 ) -> Option<Self::AddressId>;
40}
41
42impl<CC, BT> IpSasHandler<Ipv4, BT> for CC
43where
44 CC: IpDeviceStateContext<Ipv4, BT>,
45 BT: IpDeviceStateBindingsTypes,
46{
47 fn get_local_addr_id_for_remote(
48 &mut self,
49 device_id: &Self::DeviceId,
50 _remote: Option<SpecifiedAddr<Ipv4Addr>>,
51 ) -> Option<CC::AddressId> {
52 self.with_address_ids(device_id, |mut addrs, _core_ctx| addrs.next())
55 }
56}
57
58impl<CC, BT> IpSasHandler<Ipv6, BT> for CC
59where
60 CC: IpDeviceStateContext<Ipv6, BT>,
61 BT: IpDeviceStateBindingsTypes,
62{
63 fn get_local_addr_id_for_remote(
64 &mut self,
65 device_id: &Self::DeviceId,
66 remote: Option<SpecifiedAddr<Ipv6Addr>>,
67 ) -> Option<CC::AddressId> {
68 self.with_address_ids(device_id, |addrs, core_ctx| {
69 ipv6_source_address_selection::select_ipv6_source_address(
70 remote,
71 device_id,
72 addrs,
73 |addr_id| {
74 core_ctx.with_ip_address_data(
75 device_id,
76 addr_id,
77 |IpAddressData { flags: IpAddressFlags { assigned }, config }| {
78 const ASSUME_DEPRECATED: bool = true;
82 const ASSUME_TEMPORARY: bool = false;
87 let (deprecated, temporary) = config
88 .map(|c| (c.is_deprecated(), c.is_temporary()))
89 .unwrap_or((ASSUME_DEPRECATED, ASSUME_TEMPORARY));
90 SasCandidate {
91 addr_sub: addr_id.addr_sub(),
92 assigned: *assigned,
93 temporary,
94 deprecated,
95 device: device_id.clone(),
96 }
97 },
98 )
99 },
100 )
101 })
102 }
103}