1mod offline;
7mod online;
8use self::offline::*;
9use self::online::*;
10
11use crate::config::*;
12use crate::dpdk;
13use crate::filter::FilterFactory;
14use crate::lcore::SocketId;
15use crate::memory::mempool::Mempool;
16use crate::subscription::*;
17
18use std::collections::BTreeMap;
19use std::ffi::CString;
20use std::sync::Arc;
21
22use anyhow::{bail, Result};
23
24pub struct Runtime<S>
29where
30 S: Subscribable,
31{
32 #[allow(dead_code)]
33 mempools: BTreeMap<SocketId, Mempool>,
34 online: Option<OnlineRuntime<S>>,
35 pub(crate) offline: Option<OfflineRuntime<S>>, #[cfg(feature = "timing")]
37 subscription: Arc<Subscription<S>>,
38}
39
40impl<S> Runtime<S>
41where
42 S: Subscribable,
43{
44 pub fn new(config: RuntimeConfig, factory: fn() -> FilterFactory<S::Tracked>) -> Result<Self> {
56 let factory = factory();
57 let filter_str = factory.hw_filter_str.clone();
58 let subscription = Arc::new(Subscription::new(factory));
59
60 println!("Initializing Iris runtime...");
61 log::info!("Initializing EAL...");
62 dpdk::load_drivers();
63 {
64 let eal_params = config.get_eal_params();
65 let eal_params_len = eal_params.len() as i32;
66
67 let args: Vec<CString> = eal_params
68 .into_iter()
69 .map(|arg| CString::new(arg).unwrap())
70 .collect();
71 let ptrs: Vec<*mut u8> = args.iter().map(|s| s.as_ptr() as *mut u8).collect();
72
73 let ret = unsafe { dpdk::rte_eal_init(eal_params_len, ptrs.as_ptr() as *mut _) };
74 if ret < 0 {
75 bail!("Failure initializing EAL");
76 }
77 }
78
79 log::info!("Initializing Mempools...");
80 let mut mempools = BTreeMap::new();
81 let socket_ids = config.get_all_socket_ids();
82 let mtu = if let Some(online) = &config.online {
83 online.mtu
84 } else if let Some(offline) = &config.offline {
85 offline.mtu
86 } else {
87 Mempool::default_mtu()
88 };
89 for socket_id in socket_ids {
90 log::debug!("Socket ID: {}", socket_id);
91 let mempool = Mempool::new(&config.mempool, socket_id, mtu)?;
92 mempools.insert(socket_id, mempool);
93 }
94
95 let online = config.online.as_ref().map(|cfg| {
96 log::info!("Initializing Online Runtime...");
97 let online_opts = OnlineOptions {
98 online: cfg.clone(),
99 conntrack: config.conntrack.clone(),
100 };
101 OnlineRuntime::new(
102 &config,
103 online_opts,
104 &mut mempools,
105 filter_str.clone(),
106 Arc::clone(&subscription),
107 )
108 });
109
110 let offline = config.offline.as_ref().map(|cfg| {
111 log::info!("Initializing Offline Analysis...");
112 let offline_opts = OfflineOptions {
113 offline: cfg.clone(),
114 conntrack: config.conntrack.clone(),
115 };
116 OfflineRuntime::new(offline_opts, &mempools, Arc::clone(&subscription))
117 });
118
119 log::info!("Runtime ready.");
120 Ok(Runtime {
121 mempools,
122 online,
123 offline,
124 #[cfg(feature = "timing")]
125 subscription,
126 })
127 }
128
129 pub fn run(&mut self) {
135 if let Some(online) = &mut self.online {
136 online.run();
137 } else if let Some(offline) = &self.offline {
138 offline.run();
139 } else {
140 log::error!("No runtime");
141 }
142 #[cfg(feature = "timing")]
143 {
144 self.subscription.timers.display_stats();
145 self.subscription.timers.dump_stats();
146 }
147 log::info!("Done.");
148 }
149}