1use lock_order::lock::LockLevelFor;
9use lock_order::relation::LockBefore;
10use lock_order::wrap::{LockedWrapperApi, LockedWrapperUnlockedApi};
11use netstack3_base::{CoreTimerContext, CounterContext};
12use netstack3_device::{DeviceId, WeakDeviceId};
13use netstack3_ip::multicast_forwarding::{
14 MulticastForwardingCounters, MulticastForwardingEnabledState,
15 MulticastForwardingPendingPackets, MulticastForwardingPendingPacketsContext,
16 MulticastForwardingState, MulticastForwardingStateContext, MulticastForwardingTimerId,
17 MulticastRouteTable, MulticastRouteTableContext,
18};
19use netstack3_ip::IpLayerTimerId;
20
21use crate::{lock_ordering, BindingsContext, BindingsTypes, CoreCtx, IpExt};
22
23#[netstack3_macros::instantiate_ip_impl_block(I)]
24impl<
25 I: IpExt,
26 BC: BindingsContext,
27 L: LockBefore<lock_ordering::IpMulticastForwardingState<I>>,
28 > MulticastForwardingStateContext<I, BC> for CoreCtx<'_, BC, L>
29{
30 type Ctx<'a> = CoreCtx<'a, BC, lock_ordering::IpMulticastForwardingState<I>>;
31
32 fn with_state<
33 O,
34 F: FnOnce(&MulticastForwardingState<I, Self::DeviceId, BC>, &mut Self::Ctx<'_>) -> O,
35 >(
36 &mut self,
37 cb: F,
38 ) -> O {
39 let (state, mut core_ctx) =
40 self.read_lock_and::<lock_ordering::IpMulticastForwardingState<I>>();
41 cb(&state, &mut core_ctx)
42 }
43
44 fn with_state_mut<
45 O,
46 F: FnOnce(&mut MulticastForwardingState<I, Self::DeviceId, BC>, &mut Self::Ctx<'_>) -> O,
47 >(
48 &mut self,
49 cb: F,
50 ) -> O {
51 let (mut state, mut core_ctx) =
52 self.write_lock_and::<lock_ordering::IpMulticastForwardingState<I>>();
53 cb(&mut state, &mut core_ctx)
54 }
55}
56
57#[netstack3_macros::instantiate_ip_impl_block(I)]
58impl<I: IpExt, BC: BindingsContext, L: LockBefore<lock_ordering::IpMulticastRouteTable<I>>>
59 MulticastRouteTableContext<I, BC> for CoreCtx<'_, BC, L>
60{
61 type Ctx<'a> = CoreCtx<'a, BC, lock_ordering::IpMulticastRouteTable<I>>;
62
63 fn with_route_table<
64 O,
65 F: FnOnce(&MulticastRouteTable<I, Self::DeviceId, BC>, &mut Self::Ctx<'_>) -> O,
66 >(
67 &mut self,
68 state: &MulticastForwardingEnabledState<I, Self::DeviceId, BC>,
69 cb: F,
70 ) -> O {
71 let mut locked = self.adopt(state);
72 let (route_table, mut core_ctx) =
73 locked.read_lock_with_and::<lock_ordering::IpMulticastRouteTable<I>, _>(|c| c.right());
74 let mut core_ctx = core_ctx.cast_core_ctx();
75 cb(&route_table, &mut core_ctx)
76 }
77
78 fn with_route_table_mut<
79 O,
80 F: FnOnce(&mut MulticastRouteTable<I, Self::DeviceId, BC>, &mut Self::Ctx<'_>) -> O,
81 >(
82 &mut self,
83 state: &MulticastForwardingEnabledState<I, Self::DeviceId, BC>,
84 cb: F,
85 ) -> O {
86 let mut locked = self.adopt(state);
87 let (mut route_table, mut core_ctx) =
88 locked.write_lock_with_and::<lock_ordering::IpMulticastRouteTable<I>, _>(|c| c.right());
89 let mut core_ctx = core_ctx.cast_core_ctx();
90 cb(&mut route_table, &mut core_ctx)
91 }
92}
93
94#[netstack3_macros::instantiate_ip_impl_block(I)]
95impl<
96 I: IpExt,
97 BC: BindingsContext,
98 L: LockBefore<lock_ordering::IpMulticastForwardingPendingPackets<I>>,
99 > MulticastForwardingPendingPacketsContext<I, BC> for CoreCtx<'_, BC, L>
100{
101 fn with_pending_table_mut<
102 O,
103 F: FnOnce(&mut MulticastForwardingPendingPackets<I, Self::WeakDeviceId, BC>) -> O,
104 >(
105 &mut self,
106 state: &MulticastForwardingEnabledState<I, Self::DeviceId, BC>,
107 cb: F,
108 ) -> O {
109 let mut locked = self.adopt(state);
110 let mut pending_table = locked
111 .lock_with::<lock_ordering::IpMulticastForwardingPendingPackets<I>, _>(|c| c.right());
112 cb(&mut pending_table)
113 }
114}
115
116impl<I: IpExt, BT: BindingsTypes> LockLevelFor<MulticastForwardingEnabledState<I, DeviceId<BT>, BT>>
117 for lock_ordering::IpMulticastRouteTable<I>
118{
119 type Data = MulticastRouteTable<I, DeviceId<BT>, BT>;
120}
121
122impl<I: IpExt, BT: BindingsTypes> LockLevelFor<MulticastForwardingEnabledState<I, DeviceId<BT>, BT>>
123 for lock_ordering::IpMulticastForwardingPendingPackets<I>
124{
125 type Data = MulticastForwardingPendingPackets<I, WeakDeviceId<BT>, BT>;
126}
127
128impl<I, BC, L> CoreTimerContext<MulticastForwardingTimerId<I>, BC> for CoreCtx<'_, BC, L>
129where
130 I: IpExt,
131 BC: BindingsContext,
132{
133 fn convert_timer(dispatch_id: MulticastForwardingTimerId<I>) -> BC::DispatchId {
134 IpLayerTimerId::from(dispatch_id).into()
135 }
136}
137
138impl<I, BC, L> CounterContext<MulticastForwardingCounters<I>> for CoreCtx<'_, BC, L>
139where
140 I: IpExt,
141 BC: BindingsContext,
142{
143 fn counters(&self) -> &MulticastForwardingCounters<I> {
144 self.unlocked_access::<crate::lock_ordering::UnlockedState>()
145 .inner_ip_state()
146 .multicast_forwarding_counters()
147 }
148}