netstack3_core/
time.rs
1use core::convert::Infallible as Never;
8
9use derivative::Derivative;
10use log::trace;
11use net_types::ip::{GenericOverIp, Ip, Ipv4, Ipv6};
12use netstack3_base::{CoreTimerContext, HandleableTimer, TimerHandler};
13use netstack3_device::{DeviceLayerTimerId, WeakDeviceId};
14use netstack3_ip::device::{IpDeviceIpExt, IpDeviceTimerId};
15use netstack3_ip::IpLayerTimerId;
16
17use crate::context::CoreCtx;
18use crate::ip::integration::IpAddrCtxSpec;
19use crate::transport::TransportLayerTimerId;
20use crate::BindingsTypes;
21
22pub use netstack3_base::{AtomicInstant, Instant};
23
24#[derive(Derivative, GenericOverIp)]
26#[derivative(
27 Clone(bound = ""),
28 Eq(bound = ""),
29 PartialEq(bound = ""),
30 Hash(bound = ""),
31 Debug(bound = "")
32)]
33#[generic_over_ip()]
34pub struct TimerId<BT: BindingsTypes>(pub(crate) TimerIdInner<BT>);
35
36#[derive(Derivative, GenericOverIp)]
37#[derivative(
38 Clone(bound = ""),
39 Eq(bound = ""),
40 PartialEq(bound = ""),
41 Hash(bound = ""),
42 Debug(bound = "")
43)]
44#[generic_over_ip()]
45pub enum TimerIdInner<BT: BindingsTypes> {
46 DeviceLayer(DeviceLayerTimerId<BT>),
48 TransportLayer(TransportLayerTimerId<BT>),
50 IpLayer(IpLayerTimerId),
52 Ipv4Device(IpDeviceTimerId<Ipv4, WeakDeviceId<BT>, IpAddrCtxSpec<BT>>),
54 Ipv6Device(IpDeviceTimerId<Ipv6, WeakDeviceId<BT>, IpAddrCtxSpec<BT>>),
56}
57
58impl<BT: BindingsTypes> From<DeviceLayerTimerId<BT>> for TimerId<BT> {
59 fn from(id: DeviceLayerTimerId<BT>) -> TimerId<BT> {
60 TimerId(TimerIdInner::DeviceLayer(id))
61 }
62}
63
64impl<BT: BindingsTypes> From<IpLayerTimerId> for TimerId<BT> {
65 fn from(id: IpLayerTimerId) -> TimerId<BT> {
66 TimerId(TimerIdInner::IpLayer(id))
67 }
68}
69
70impl<BT: BindingsTypes> From<TransportLayerTimerId<BT>> for TimerId<BT> {
71 fn from(id: TransportLayerTimerId<BT>) -> Self {
72 TimerId(TimerIdInner::TransportLayer(id))
73 }
74}
75
76impl<BT: BindingsTypes, I: IpDeviceIpExt>
77 From<IpDeviceTimerId<I, WeakDeviceId<BT>, IpAddrCtxSpec<BT>>> for TimerId<BT>
78{
79 fn from(value: IpDeviceTimerId<I, WeakDeviceId<BT>, IpAddrCtxSpec<BT>>) -> Self {
80 I::map_ip(
81 value,
82 |v4| TimerId(TimerIdInner::Ipv4Device(v4)),
83 |v6| TimerId(TimerIdInner::Ipv6Device(v6)),
84 )
85 }
86}
87
88impl<CC, BT> HandleableTimer<CC, BT> for TimerId<BT>
89where
90 BT: BindingsTypes,
91 CC: TimerHandler<BT, DeviceLayerTimerId<BT>>
92 + TimerHandler<BT, TransportLayerTimerId<BT>>
93 + TimerHandler<BT, IpLayerTimerId>
94 + TimerHandler<BT, IpDeviceTimerId<Ipv4, WeakDeviceId<BT>, IpAddrCtxSpec<BT>>>
95 + TimerHandler<BT, IpDeviceTimerId<Ipv6, WeakDeviceId<BT>, IpAddrCtxSpec<BT>>>,
96{
97 fn handle(self, core_ctx: &mut CC, bindings_ctx: &mut BT, timer: BT::UniqueTimerId) {
98 trace!("handle_timer: dispatching timerid: {self:?}");
99 match self {
100 TimerId(TimerIdInner::DeviceLayer(x)) => core_ctx.handle_timer(bindings_ctx, x, timer),
101 TimerId(TimerIdInner::TransportLayer(x)) => {
102 core_ctx.handle_timer(bindings_ctx, x, timer)
103 }
104 TimerId(TimerIdInner::IpLayer(x)) => core_ctx.handle_timer(bindings_ctx, x, timer),
105 TimerId(TimerIdInner::Ipv4Device(x)) => core_ctx.handle_timer(bindings_ctx, x, timer),
106 TimerId(TimerIdInner::Ipv6Device(x)) => core_ctx.handle_timer(bindings_ctx, x, timer),
107 }
108 }
109}
110
111impl<'a, BT, L> CoreTimerContext<Never, BT> for CoreCtx<'a, BT, L>
112where
113 BT: BindingsTypes,
114{
115 fn convert_timer(dispatch_id: Never) -> <BT as netstack3_base::TimerBindingsTypes>::DispatchId {
116 match dispatch_id {}
117 }
118}