diff --git a/src/rust/lqos_config/src/network_json/mod.rs b/src/rust/lqos_config/src/network_json/mod.rs index 1bd3924b..71dbad0a 100644 --- a/src/rust/lqos_config/src/network_json/mod.rs +++ b/src/rust/lqos_config/src/network_json/mod.rs @@ -193,7 +193,11 @@ fn recurse_node( immediate_parent: usize, ) { info!("Mapping {name} from network.json"); - let mut my_id = nodes.len(); + let my_id = if name != "children" { + nodes.len() + } else { + nodes.len()-1 + }; let mut parents = parents.to_vec(); parents.push(my_id); let node = NetworkJsonNode { @@ -210,8 +214,6 @@ fn recurse_node( if node.name != "children" { nodes.push(node); - } else { - my_id -= 1; } // Recurse children diff --git a/src/rust/lqos_node_manager/src/main.rs b/src/rust/lqos_node_manager/src/main.rs index b9fe840b..c9cd4cec 100644 --- a/src/rust/lqos_node_manager/src/main.rs +++ b/src/rust/lqos_node_manager/src/main.rs @@ -80,6 +80,7 @@ fn rocket() -> _ { static_pages::login_page, auth_guard::username, network_tree::tree_entry, + network_tree::tree_clients, // Supporting files static_pages::bootsrap_css, static_pages::plotly_js, diff --git a/src/rust/lqos_node_manager/src/network_tree.rs b/src/rust/lqos_node_manager/src/network_tree.rs index c79c065d..f4b73701 100644 --- a/src/rust/lqos_node_manager/src/network_tree.rs +++ b/src/rust/lqos_node_manager/src/network_tree.rs @@ -1,8 +1,10 @@ +use std::net::IpAddr; + use lqos_bus::{bus_request, BusRequest, BusResponse}; use lqos_config::NetworkJsonNode; -use rocket::{fs::NamedFile, serde::json::Json}; +use rocket::{fs::NamedFile, serde::{json::Json, Serialize}}; -use crate::cache_control::NoCache; +use crate::{cache_control::NoCache, tracker::SHAPED_DEVICES}; // Note that NoCache can be replaced with a cache option // once the design work is complete. @@ -24,3 +26,46 @@ pub async fn tree_entry( NoCache::new(Json(result)) } + +#[derive(Serialize, Clone)] +#[serde(crate = "rocket::serde")] +pub struct CircuitThroughput { + pub id: String, + pub name: String, + pub traffic: (u64, u64), + pub limit: (u64, u64), +} + +#[get("/api/tree_clients/")] +pub async fn tree_clients( + parent: String, +) -> NoCache>> { + let mut result = Vec::new(); + for msg in + bus_request(vec![BusRequest::GetHostCounter]).await.unwrap().iter() + { + let devices = SHAPED_DEVICES.read(); + if let BusResponse::HostCounters(hosts) = msg { + for (ip, down, up) in hosts.iter() { + let lookup = match ip { + IpAddr::V4(ip) => ip.to_ipv6_mapped(), + IpAddr::V6(ip) => *ip, + }; + if let Some(c) = devices.trie.longest_match(lookup) { + if devices.devices[*c.1].parent_node == parent { + result.push(CircuitThroughput { + id: devices.devices[*c.1].circuit_id.clone(), + name: devices.devices[*c.1].circuit_name.clone(), + traffic: (*down, *up), + limit: ( + devices.devices[*c.1].download_max_mbps as u64, + devices.devices[*c.1].upload_max_mbps as u64, + ) + }); + } + } + } + } + } + NoCache::new(Json(result)) +} diff --git a/src/rust/lqos_node_manager/static/lqos.js b/src/rust/lqos_node_manager/static/lqos.js index 3d592f31..9d5ecb21 100644 --- a/src/rust/lqos_node_manager/static/lqos.js +++ b/src/rust/lqos_node_manager/static/lqos.js @@ -188,4 +188,34 @@ const reloadModal = ` - `; \ No newline at end of file + `; + +class RingBuffer { + constructor(capacity) { + this.capacity = capacity; + this.head = capacity-1; + this.download = []; + this.upload = []; + this.x_axis = []; + for (var i=0; i + @@ -12,41 +13,49 @@ +