1use lock_order::lock::LockLevelFor;
9use lock_order::relation::LockBefore;
10use lock_order::wrap::{LockedWrapperApi, LockedWrapperUnlockedApi};
11use netstack3_base::{CounterContext, ResourceCounterContext, WeakDeviceIdentifier};
12use netstack3_device::WeakDeviceId;
13use netstack3_ip::raw::{
14 RawIpSocketCounters, RawIpSocketId, RawIpSocketLockedState, RawIpSocketMap,
15 RawIpSocketMapContext, RawIpSocketState, RawIpSocketStateContext,
16};
17
18use crate::marker::IpExt;
19use crate::{lock_ordering, BindingsContext, BindingsTypes, CoreCtx};
20
21#[netstack3_macros::instantiate_ip_impl_block(I)]
22impl<I: IpExt, BC: BindingsContext, L: LockBefore<lock_ordering::RawIpSocketState<I>>>
23 RawIpSocketStateContext<I, BC> for CoreCtx<'_, BC, L>
24{
25 type SocketHandler<'a> = CoreCtx<'a, BC, lock_ordering::RawIpSocketState<I>>;
26
27 fn with_locked_state<O, F: FnOnce(&RawIpSocketLockedState<I, Self::WeakDeviceId>) -> O>(
28 &mut self,
29 id: &RawIpSocketId<I, Self::WeakDeviceId, BC>,
30 cb: F,
31 ) -> O {
32 let mut locked = self.adopt(id.state());
33 let guard = locked.read_lock_with::<lock_ordering::RawIpSocketState<I>, _>(|c| c.right());
34 cb(&guard)
35 }
36 fn with_locked_state_and_socket_handler<
37 O,
38 F: FnOnce(&RawIpSocketLockedState<I, Self::WeakDeviceId>, &mut Self::SocketHandler<'_>) -> O,
39 >(
40 &mut self,
41 id: &RawIpSocketId<I, Self::WeakDeviceId, BC>,
42 cb: F,
43 ) -> O {
44 let mut locked = self.adopt(id.state());
45 let (state, mut core_ctx) =
46 locked.read_lock_with_and::<lock_ordering::RawIpSocketState<I>, _>(|c| c.right());
47 let mut core_ctx = core_ctx.cast_core_ctx();
48 cb(&state, &mut core_ctx)
49 }
50 fn with_locked_state_mut<
51 O,
52 F: FnOnce(&mut RawIpSocketLockedState<I, Self::WeakDeviceId>) -> O,
53 >(
54 &mut self,
55 id: &RawIpSocketId<I, Self::WeakDeviceId, BC>,
56 cb: F,
57 ) -> O {
58 let mut locked = self.adopt(id.state());
59 let mut guard =
60 locked.write_lock_with::<lock_ordering::RawIpSocketState<I>, _>(|c| c.right());
61 cb(&mut guard)
62 }
63}
64
65#[netstack3_macros::instantiate_ip_impl_block(I)]
66impl<I: IpExt, BC: BindingsContext, L: LockBefore<lock_ordering::AllRawIpSockets<I>>>
67 RawIpSocketMapContext<I, BC> for CoreCtx<'_, BC, L>
68{
69 type StateCtx<'a> = CoreCtx<'a, BC, lock_ordering::AllRawIpSockets<I>>;
70
71 fn with_socket_map_and_state_ctx<
72 O,
73 F: FnOnce(&RawIpSocketMap<I, Self::WeakDeviceId, BC>, &mut Self::StateCtx<'_>) -> O,
74 >(
75 &mut self,
76 cb: F,
77 ) -> O {
78 let (sockets, mut core_ctx) = self.read_lock_and::<lock_ordering::AllRawIpSockets<I>>();
79 cb(&sockets, &mut core_ctx)
80 }
81 fn with_socket_map_mut<O, F: FnOnce(&mut RawIpSocketMap<I, Self::WeakDeviceId, BC>) -> O>(
82 &mut self,
83 cb: F,
84 ) -> O {
85 let mut sockets = self.write_lock::<lock_ordering::AllRawIpSockets<I>>();
86 cb(&mut sockets)
87 }
88}
89
90impl<I: IpExt, BT: BindingsTypes> LockLevelFor<RawIpSocketState<I, WeakDeviceId<BT>, BT>>
91 for lock_ordering::RawIpSocketState<I>
92{
93 type Data = RawIpSocketLockedState<I, WeakDeviceId<BT>>;
94}
95
96impl<I: IpExt, BC: BindingsContext, L> CounterContext<RawIpSocketCounters<I>>
97 for CoreCtx<'_, BC, L>
98{
99 fn counters(&self) -> &RawIpSocketCounters<I> {
100 self.unlocked_access::<crate::lock_ordering::UnlockedState>()
101 .inner_ip_state()
102 .raw_ip_socket_counters()
103 }
104}
105
106impl<I: IpExt, BC: BindingsContext, L, D: WeakDeviceIdentifier>
109 ResourceCounterContext<RawIpSocketId<I, D, BC>, RawIpSocketCounters<I>> for CoreCtx<'_, BC, L>
110{
111 fn per_resource_counters<'a>(
112 &'a self,
113 id: &'a RawIpSocketId<I, D, BC>,
114 ) -> &'a RawIpSocketCounters<I> {
115 id.state().counters()
120 }
121}