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