batman_robin/model/gateway_event.rs
1use macaddr::MacAddr;
2use std::time::SystemTime;
3
4/// Gateway change event emitted by batman-adv kernel module.
5///
6/// When a batman-adv node is in gateway client mode, it emits uevents
7/// when the selected gateway changes. Applications can subscribe to these
8/// events to perform actions like starting/renewing DHCP leases.
9///
10/// # Examples
11///
12/// ```ignore
13/// let client = batman_robin::Client::new();
14/// let mut events = client
15/// .subscribe_gateway_events(batman_robin::MeshSelector::with_name("bat0"))
16/// .await?;
17///
18/// while let Some(event) = events.next().await {
19/// match event?.action {
20/// GatewayEventAction::Add => println!("Gateway selected: {:?}", event?.gateway_mac),
21/// GatewayEventAction::Change => println!("Better gateway found"),
22/// GatewayEventAction::Delete => println!("Gateway lost"),
23/// }
24/// }
25/// ```
26#[derive(Debug, Clone, PartialEq, Eq)]
27pub struct GatewayEvent {
28 /// Timestamp when the event was received
29 pub timestamp: SystemTime,
30
31 /// Mesh interface index (e.g. from `if_nametoindex("bat0")`)
32 pub meshif: u32,
33
34 /// Mesh interface name (e.g. "bat0")
35 pub meshif_name: String,
36
37 /// Type of gateway change event
38 pub action: GatewayEventAction,
39
40 /// MAC address of the selected gateway (present for ADD/CHANGE, absent for DELETE)
41 pub gateway_mac: Option<MacAddr>,
42}
43
44/// Gateway event action types
45///
46/// These correspond to batman-adv's BATACTION uevent field.
47#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
48#[repr(u8)]
49pub enum GatewayEventAction {
50 /// First gateway was selected (ADD)
51 ///
52 /// This event is sent when a batman-adv node transitions to having a selected
53 /// gateway. Applications should typically start a DHCP client on this event.
54 Add = 1,
55
56 /// A better gateway was found (CHANGE)
57 ///
58 /// This event is sent when a batman-adv node switches to a different gateway
59 /// due to improved link quality or other selection criteria.
60 /// Applications should typically renew their DHCP lease on this event.
61 Change = 2,
62
63 /// The selected gateway is no longer available (DEL)
64 ///
65 /// This event is sent when the currently selected gateway disappears
66 /// and no alternative gateway is available. The `gateway_mac` field
67 /// will be `None` for this action.
68 Delete = 3,
69}
70
71impl GatewayEvent {
72 /// Create a new gateway event
73 pub fn new(
74 meshif: u32,
75 meshif_name: String,
76 action: GatewayEventAction,
77 gateway_mac: Option<MacAddr>,
78 ) -> Self {
79 Self {
80 timestamp: SystemTime::now(),
81 meshif,
82 meshif_name,
83 action,
84 gateway_mac,
85 }
86 }
87
88 /// Check if this event has a valid associated gateway MAC
89 pub fn has_gateway(&self) -> bool {
90 self.gateway_mac.is_some()
91 }
92}
93
94impl std::fmt::Display for GatewayEventAction {
95 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
96 match self {
97 Self::Add => write!(f, "ADD"),
98 Self::Change => write!(f, "CHANGE"),
99 Self::Delete => write!(f, "DELETE"),
100 }
101 }
102}
103
104#[cfg(test)]
105mod tests {
106 use super::*;
107
108 #[test]
109 fn test_gateway_event_creation() {
110 let mac = "60:09:c3:aa:bb:cc".parse().unwrap();
111 let event = GatewayEvent::new(6, "bat0".to_string(), GatewayEventAction::Add, Some(mac));
112
113 assert_eq!(event.meshif, 6);
114 assert_eq!(event.meshif_name, "bat0");
115 assert_eq!(event.action, GatewayEventAction::Add);
116 assert_eq!(event.gateway_mac, Some(mac));
117 assert!(event.has_gateway());
118 }
119
120 #[test]
121 fn test_delete_event_no_gateway() {
122 let event = GatewayEvent::new(6, "bat0".to_string(), GatewayEventAction::Delete, None);
123
124 assert_eq!(event.action, GatewayEventAction::Delete);
125 assert!(!event.has_gateway());
126 }
127
128 #[test]
129 fn test_action_display() {
130 assert_eq!(GatewayEventAction::Add.to_string(), "ADD");
131 assert_eq!(GatewayEventAction::Change.to_string(), "CHANGE");
132 assert_eq!(GatewayEventAction::Delete.to_string(), "DELETE");
133 }
134}