mirror of
https://github.com/LibreQoE/LibreQoS.git
synced 2025-02-25 18:55:32 -06:00
Now featuring capacities from UISP, applied and moved around for squashing.
This commit is contained in:
parent
d13a17821a
commit
b93486ee4c
@ -1,4 +1,5 @@
|
||||
use crate::uisp_types::{UispSite, UispSiteType};
|
||||
use crate::uisp_types::{UispDevice, UispSite, UispSiteType};
|
||||
use lqos_config::Config;
|
||||
use std::collections::HashSet;
|
||||
use tracing::info;
|
||||
use uisp::{DataLink, Device, Site};
|
||||
@ -8,6 +9,8 @@ pub fn promote_access_points(
|
||||
devices_raw: &[Device],
|
||||
data_links_raw: &[DataLink],
|
||||
sites_raw: &[Site],
|
||||
devices: &[UispDevice],
|
||||
config: &Config,
|
||||
) {
|
||||
let mut all_links = Vec::new();
|
||||
sites.iter().for_each(|s| {
|
||||
@ -28,14 +31,22 @@ pub fn promote_access_points(
|
||||
sites[parent_site_id].name
|
||||
);
|
||||
}*/
|
||||
|
||||
let mut max_up_mbps = config.queues.generated_pn_upload_mbps;
|
||||
let mut max_down_mbps = config.queues.generated_pn_download_mbps;
|
||||
if let Some(ap) = devices.iter().find(|d| d.id == link.device_id) {
|
||||
max_up_mbps = ap.upload;
|
||||
max_down_mbps = ap.download;
|
||||
}
|
||||
|
||||
let mut new_site = UispSite {
|
||||
id: link.device_id,
|
||||
name: link.device_name,
|
||||
site_type: UispSiteType::AccessPoint,
|
||||
uisp_parent_id: None,
|
||||
parent_indices: HashSet::new(),
|
||||
max_up_mbps: 0, // TODO: I need to read this from the device capacity
|
||||
max_down_mbps: 0,
|
||||
max_up_mbps,
|
||||
max_down_mbps,
|
||||
..Default::default()
|
||||
};
|
||||
new_site.parent_indices.insert(parent_site_id);
|
||||
|
@ -46,7 +46,9 @@ pub fn promote_clients_with_children(
|
||||
suspended: sites[child_site].suspended,
|
||||
..Default::default()
|
||||
};
|
||||
new_site.device_indices.extend_from_slice(&sites[child_site].device_indices);
|
||||
new_site
|
||||
.device_indices
|
||||
.extend_from_slice(&sites[child_site].device_indices);
|
||||
sites[child_site].device_indices.clear();
|
||||
sites.push(new_site);
|
||||
}
|
||||
|
@ -2,28 +2,28 @@ mod ap_promotion;
|
||||
mod client_site_promotion;
|
||||
mod parse;
|
||||
mod root_site;
|
||||
mod uisp_fetch;
|
||||
mod utils;
|
||||
mod squash_single_entry_aps;
|
||||
mod tree_walk;
|
||||
mod uisp_fetch;
|
||||
mod utils;
|
||||
|
||||
use crate::errors::UispIntegrationError;
|
||||
use crate::strategies::full::ap_promotion::promote_access_points;
|
||||
use crate::strategies::full::client_site_promotion::promote_clients_with_children;
|
||||
use crate::strategies::full::parse::parse_uisp_datasets;
|
||||
use crate::strategies::full::root_site::{find_root_site, set_root_site};
|
||||
use crate::strategies::full::uisp_fetch::load_uisp_data;
|
||||
use crate::strategies::full::utils::{print_sites, warn_of_no_parents};
|
||||
use lqos_config::Config;
|
||||
use crate::strategies::full::squash_single_entry_aps::squash_single_aps;
|
||||
use crate::strategies::full::tree_walk::walk_tree_for_routing;
|
||||
use crate::strategies::full::uisp_fetch::load_uisp_data;
|
||||
use crate::strategies::full::utils::{print_sites, warn_of_no_parents};
|
||||
use crate::uisp_types::UispSite;
|
||||
use lqos_config::Config;
|
||||
|
||||
/// Attempt to construct a full hierarchy topology for the UISP network.
|
||||
pub async fn build_full_network(config: Config) -> Result<(), UispIntegrationError> {
|
||||
// Obtain the UISP data and transform it into easier to work with types
|
||||
let (sites_raw, devices_raw, data_links_raw) = load_uisp_data(config.clone()).await?;
|
||||
let (mut sites, data_links, _devices) =
|
||||
let (mut sites, data_links, devices) =
|
||||
parse_uisp_datasets(&sites_raw, &data_links_raw, &devices_raw, &config);
|
||||
|
||||
// Check root sites
|
||||
@ -33,7 +33,14 @@ pub async fn build_full_network(config: Config) -> Result<(), UispIntegrationErr
|
||||
set_root_site(&mut sites, &root_site)?;
|
||||
|
||||
// Search for devices that provide links elsewhere
|
||||
promote_access_points(&mut sites, &devices_raw, &data_links_raw, &sites_raw);
|
||||
promote_access_points(
|
||||
&mut sites,
|
||||
&devices_raw,
|
||||
&data_links_raw,
|
||||
&sites_raw,
|
||||
&devices,
|
||||
&config,
|
||||
);
|
||||
|
||||
// Sites that are clients but have children should be promoted
|
||||
promote_clients_with_children(&mut sites)?;
|
||||
@ -55,15 +62,20 @@ pub async fn build_full_network(config: Config) -> Result<(), UispIntegrationErr
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn walk_node(idx: usize, weight: u32, sites: &mut Vec<UispSite>, visited: &mut std::collections::HashSet<usize>) {
|
||||
fn walk_node(
|
||||
idx: usize,
|
||||
weight: u32,
|
||||
sites: &mut Vec<UispSite>,
|
||||
visited: &mut std::collections::HashSet<usize>,
|
||||
) {
|
||||
if visited.contains(&idx) {
|
||||
return;
|
||||
}
|
||||
visited.insert(idx);
|
||||
for i in 0 .. sites.len() {
|
||||
for i in 0..sites.len() {
|
||||
if sites[i].parent_indices.contains(&idx) {
|
||||
sites[i].route_weights.push((idx, weight));
|
||||
walk_node(i, weight+10, sites, visited);
|
||||
walk_node(i, weight + 10, sites, visited);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,16 +12,18 @@ pub fn parse_uisp_datasets(
|
||||
let (mut sites, data_links, devices) = (
|
||||
parse_sites(sites_raw, config),
|
||||
parse_data_links(data_links_raw, devices_raw),
|
||||
parse_devices(devices_raw),
|
||||
parse_devices(devices_raw, config),
|
||||
);
|
||||
|
||||
// Assign devices to sites
|
||||
for site in sites.iter_mut() {
|
||||
devices.iter().enumerate().filter(|(_, device)|
|
||||
device.site_id == site.id
|
||||
).for_each(|(idx, _)| {
|
||||
site.device_indices.push(idx);
|
||||
});
|
||||
devices
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|(_, device)| device.site_id == site.id)
|
||||
.for_each(|(idx, _)| {
|
||||
site.device_indices.push(idx);
|
||||
});
|
||||
}
|
||||
|
||||
(sites, data_links, devices)
|
||||
@ -49,10 +51,10 @@ fn parse_data_links(data_links_raw: &[DataLink], devices_raw: &[Device]) -> Vec<
|
||||
data_links
|
||||
}
|
||||
|
||||
fn parse_devices(devices_raw: &[Device]) -> Vec<UispDevice> {
|
||||
fn parse_devices(devices_raw: &[Device], config: &Config) -> Vec<UispDevice> {
|
||||
let mut devices: Vec<UispDevice> = devices_raw
|
||||
.iter()
|
||||
.map(|d| UispDevice::from_uisp(d))
|
||||
.map(|d| UispDevice::from_uisp(d, config))
|
||||
.collect();
|
||||
info!("{} devices have been sucessfully parsed", devices.len());
|
||||
devices
|
||||
|
@ -5,7 +5,10 @@ pub fn squash_single_aps(sites: &mut Vec<UispSite>) -> Result<(), UispIntegratio
|
||||
let mut squashable = Vec::new();
|
||||
for (idx, site) in sites.iter().enumerate() {
|
||||
if site.site_type == UispSiteType::AccessPoint {
|
||||
let target_count = sites.iter().filter(|s| s.parent_indices.contains(&idx)).count();
|
||||
let target_count = sites
|
||||
.iter()
|
||||
.filter(|s| s.parent_indices.contains(&idx))
|
||||
.count();
|
||||
if target_count == 1 && site.parent_indices.len() == 1 {
|
||||
//tracing::info!("Site {} has only one child and is therefore eligible for squashing.", site.name);
|
||||
squashable.push(idx);
|
||||
@ -15,15 +18,19 @@ pub fn squash_single_aps(sites: &mut Vec<UispSite>) -> Result<(), UispIntegratio
|
||||
for squash_idx in squashable {
|
||||
sites[squash_idx].site_type = UispSiteType::SquashDeleted;
|
||||
sites[squash_idx].name += " (SQUASHED)";
|
||||
let up = sites[squash_idx].max_up_mbps;
|
||||
let down = sites[squash_idx].max_down_mbps;
|
||||
let new_parent = *sites[squash_idx].parent_indices.iter().nth(0).unwrap();
|
||||
sites.iter_mut().for_each(|s| {
|
||||
if s.parent_indices.contains(&squash_idx) {
|
||||
s.parent_indices.remove(&squash_idx);
|
||||
s.parent_indices.insert(new_parent);
|
||||
s.max_up_mbps = up;
|
||||
s.max_down_mbps = down;
|
||||
}
|
||||
});
|
||||
sites[squash_idx].parent_indices.clear();
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,10 @@ use crate::errors::UispIntegrationError;
|
||||
use crate::strategies::full::walk_node;
|
||||
use crate::uisp_types::{UispSite, UispSiteType};
|
||||
|
||||
pub fn walk_tree_for_routing(sites: &mut Vec<UispSite>, root_site: &str) -> Result<(), UispIntegrationError> {
|
||||
pub fn walk_tree_for_routing(
|
||||
sites: &mut Vec<UispSite>,
|
||||
root_site: &str,
|
||||
) -> Result<(), UispIntegrationError> {
|
||||
if let Some(root_idx) = sites.iter().position(|s| s.name == root_site) {
|
||||
let mut visited = std::collections::HashSet::new();
|
||||
let mut current_node = root_idx;
|
||||
@ -16,12 +19,10 @@ pub fn walk_tree_for_routing(sites: &mut Vec<UispSite>, root_site: &str) -> Resu
|
||||
for site in sites.iter_mut() {
|
||||
if site.site_type != UispSiteType::Root && !site.route_weights.is_empty() {
|
||||
// Sort to find the lowest exit
|
||||
site.route_weights.sort_by(|a,b| {
|
||||
a.1.cmp(&b.1)
|
||||
});
|
||||
site.route_weights.sort_by(|a, b| a.1.cmp(&b.1));
|
||||
site.selected_parent = Some(site.route_weights[0].0);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
use lqos_config::Config;
|
||||
use uisp::Device;
|
||||
|
||||
/// Trimmed UISP device for easy use
|
||||
@ -5,20 +6,36 @@ pub struct UispDevice {
|
||||
pub id: String,
|
||||
pub mac: String,
|
||||
pub site_id: String,
|
||||
pub download: u32,
|
||||
pub upload: u32,
|
||||
}
|
||||
|
||||
impl UispDevice {
|
||||
pub fn from_uisp(device: &Device) -> Self {
|
||||
pub fn from_uisp(device: &Device, config: &Config) -> Self {
|
||||
let mac = if let Some(id) = &device.identification.mac {
|
||||
id.clone()
|
||||
} else {
|
||||
"".to_string()
|
||||
};
|
||||
|
||||
let mut download = config.queues.generated_pn_download_mbps;
|
||||
let mut upload = config.queues.generated_pn_upload_mbps;
|
||||
if let Some(overview) = &device.overview {
|
||||
println!("{:?}", overview);
|
||||
if let Some(dl) = overview.downlinkCapacity {
|
||||
download = dl as u32 / 1000000;
|
||||
}
|
||||
if let Some(ul) = overview.uplinkCapacity {
|
||||
upload = ul as u32 / 1000000;
|
||||
}
|
||||
}
|
||||
|
||||
Self {
|
||||
id: device.get_id(),
|
||||
mac,
|
||||
site_id: device.get_site_id().unwrap_or("".to_string())
|
||||
site_id: device.get_site_id().unwrap_or("".to_string()),
|
||||
upload,
|
||||
download,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user