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