1use alloc::vec::Vec;
9use lock_order::lock::LockLevelFor;
10use lock_order::relation::LockBefore;
11use lock_order::wrap::LockedWrapperApi;
12use net_types::ip::Ip;
13use netstack3_base::DeviceIdContext;
14use netstack3_device::pure_ip::{
15 DynamicPureIpDeviceState, PureIpDevice, PureIpDeviceId, PureIpDeviceStateContext,
16 PureIpDeviceTxQueueFrameMetadata, PureIpPrimaryDeviceId, PureIpWeakDeviceId,
17};
18use netstack3_device::queue::{
19 BufVecU8Allocator, DequeueState, TransmitDequeueContext, TransmitQueueCommon,
20 TransmitQueueContext, TransmitQueueState,
21};
22use netstack3_device::socket::{IpFrame, ParseSentFrameError, SentFrame};
23use netstack3_device::{
24 DeviceCollectionContext, DeviceConfigurationContext, DeviceLayerEventDispatcher,
25 DeviceSendFrameError, IpLinkDeviceState,
26};
27use netstack3_ip::nud::NudUserConfig;
28use packet::Buf;
29
30use crate::device::integration;
31use crate::{BindingsContext, BindingsTypes, CoreCtx};
32
33impl<BT: BindingsTypes, L> DeviceIdContext<PureIpDevice> for CoreCtx<'_, BT, L> {
34 type DeviceId = PureIpDeviceId<BT>;
35 type WeakDeviceId = PureIpWeakDeviceId<BT>;
36}
37
38impl<'a, BT, L> DeviceCollectionContext<PureIpDevice, BT> for CoreCtx<'a, BT, L>
39where
40 BT: BindingsTypes,
41 L: LockBefore<crate::lock_ordering::DeviceLayerState>,
42{
43 fn insert(&mut self, device: PureIpPrimaryDeviceId<BT>) {
44 let mut devices = self.write_lock::<crate::lock_ordering::DeviceLayerState>();
45 let strong = device.clone_strong();
46 assert!(devices.pure_ip.insert(strong, device).is_none());
47 }
48
49 fn remove(&mut self, device: &PureIpDeviceId<BT>) -> Option<PureIpPrimaryDeviceId<BT>> {
50 let mut devices = self.write_lock::<crate::lock_ordering::DeviceLayerState>();
51 devices.pure_ip.remove(device)
52 }
53}
54
55impl<'a, BT, L> DeviceConfigurationContext<PureIpDevice> for CoreCtx<'a, BT, L>
56where
57 BT: BindingsTypes,
58{
59 fn with_nud_config<I: Ip, O, F: FnOnce(Option<&NudUserConfig>) -> O>(
60 &mut self,
61 _device_id: &Self::DeviceId,
62 f: F,
63 ) -> O {
64 f(None)
66 }
67
68 fn with_nud_config_mut<I: Ip, O, F: FnOnce(Option<&mut NudUserConfig>) -> O>(
69 &mut self,
70 _device_id: &Self::DeviceId,
71 f: F,
72 ) -> O {
73 f(None)
75 }
76}
77
78impl<BC: BindingsContext, L: LockBefore<crate::lock_ordering::PureIpDeviceTxQueue>>
79 TransmitQueueCommon<PureIpDevice, BC> for CoreCtx<'_, BC, L>
80{
81 type Meta = PureIpDeviceTxQueueFrameMetadata<BC>;
82 type Allocator = BufVecU8Allocator;
83 type Buffer = Buf<Vec<u8>>;
84 type DequeueContext = BC::DequeueContext;
85
86 fn parse_outgoing_frame<'a, 'b>(
87 buf: &'a [u8],
88 meta: &'b Self::Meta,
89 ) -> Result<SentFrame<&'a [u8]>, ParseSentFrameError> {
90 let PureIpDeviceTxQueueFrameMetadata { ip_version, tx_metadata: _ } = meta;
91 Ok(SentFrame::Ip(IpFrame { ip_version: *ip_version, body: buf }))
95 }
96}
97
98impl<BC: BindingsContext, L: LockBefore<crate::lock_ordering::PureIpDeviceTxQueue>>
99 TransmitQueueContext<PureIpDevice, BC> for CoreCtx<'_, BC, L>
100{
101 fn with_transmit_queue_mut<
102 O,
103 F: FnOnce(&mut TransmitQueueState<Self::Meta, Self::Buffer, Self::Allocator>) -> O,
104 >(
105 &mut self,
106 device_id: &Self::DeviceId,
107 cb: F,
108 ) -> O {
109 let mut state = integration::device_state(self, device_id);
110 let mut x = state.lock::<crate::lock_ordering::PureIpDeviceTxQueue>();
111 cb(&mut x)
112 }
113
114 fn with_transmit_queue<
115 O,
116 F: FnOnce(&TransmitQueueState<Self::Meta, Self::Buffer, Self::Allocator>) -> O,
117 >(
118 &mut self,
119 device_id: &Self::DeviceId,
120 cb: F,
121 ) -> O {
122 let mut state = integration::device_state(self, device_id);
123 let x = state.lock::<crate::lock_ordering::PureIpDeviceTxQueue>();
124 cb(&x)
125 }
126
127 fn send_frame(
128 &mut self,
129 bindings_ctx: &mut BC,
130 device_id: &Self::DeviceId,
131 dequeue_context: Option<&mut BC::DequeueContext>,
132 meta: Self::Meta,
133 buf: Self::Buffer,
134 ) -> Result<(), DeviceSendFrameError> {
135 let PureIpDeviceTxQueueFrameMetadata {
136 ip_version,
137 tx_metadata: _tx_metadata,
139 } = meta;
140 DeviceLayerEventDispatcher::send_ip_packet(
141 bindings_ctx,
142 device_id,
143 buf,
144 ip_version,
145 dequeue_context,
146 )
147 }
148}
149
150impl<BC: BindingsContext, L: LockBefore<crate::lock_ordering::PureIpDeviceTxDequeue>>
151 TransmitDequeueContext<PureIpDevice, BC> for CoreCtx<'_, BC, L>
152{
153 type TransmitQueueCtx<'a> = CoreCtx<'a, BC, crate::lock_ordering::PureIpDeviceTxDequeue>;
154
155 fn with_dequed_packets_and_tx_queue_ctx<
156 O,
157 F: FnOnce(&mut DequeueState<Self::Meta, Self::Buffer>, &mut Self::TransmitQueueCtx<'_>) -> O,
158 >(
159 &mut self,
160 device_id: &Self::DeviceId,
161 cb: F,
162 ) -> O {
163 let mut core_ctx_and_resource = integration::device_state_and_core_ctx(self, device_id);
164 let (mut x, mut locked) = core_ctx_and_resource
165 .lock_with_and::<crate::lock_ordering::PureIpDeviceTxDequeue, _>(|c| c.right());
166 cb(&mut x, &mut locked.cast_core_ctx())
167 }
168}
169
170impl<BT: BindingsTypes> LockLevelFor<IpLinkDeviceState<PureIpDevice, BT>>
171 for crate::lock_ordering::PureIpDeviceDynamicState
172{
173 type Data = DynamicPureIpDeviceState;
174}
175
176impl<BT: BindingsTypes> LockLevelFor<IpLinkDeviceState<PureIpDevice, BT>>
177 for crate::lock_ordering::PureIpDeviceTxQueue
178{
179 type Data =
180 TransmitQueueState<PureIpDeviceTxQueueFrameMetadata<BT>, Buf<Vec<u8>>, BufVecU8Allocator>;
181}
182
183impl<BT: BindingsTypes> LockLevelFor<IpLinkDeviceState<PureIpDevice, BT>>
184 for crate::lock_ordering::PureIpDeviceTxDequeue
185{
186 type Data = DequeueState<PureIpDeviceTxQueueFrameMetadata<BT>, Buf<Vec<u8>>>;
187}
188
189impl<BC: BindingsContext, L: LockBefore<crate::lock_ordering::PureIpDeviceDynamicState>>
190 PureIpDeviceStateContext for CoreCtx<'_, BC, L>
191{
192 fn with_pure_ip_state<O, F: FnOnce(&DynamicPureIpDeviceState) -> O>(
193 &mut self,
194 device_id: &Self::DeviceId,
195 cb: F,
196 ) -> O {
197 let mut state = integration::device_state(self, device_id);
198 let dynamic_state = state.read_lock::<crate::lock_ordering::PureIpDeviceDynamicState>();
199 cb(&dynamic_state)
200 }
201
202 fn with_pure_ip_state_mut<O, F: FnOnce(&mut DynamicPureIpDeviceState) -> O>(
203 &mut self,
204 device_id: &Self::DeviceId,
205 cb: F,
206 ) -> O {
207 let mut state = integration::device_state(self, device_id);
208 let mut dynamic_state =
209 state.write_lock::<crate::lock_ordering::PureIpDeviceDynamicState>();
210 cb(&mut dynamic_state)
211 }
212}