Skip to content

Commit

Permalink
Merge pull request #634 from LibreQoE/uisp_integration_routing
Browse files Browse the repository at this point in the history
Uisp integration routing
  • Loading branch information
rchac authored Jan 15, 2025
2 parents 0cb9ef6 + 327ae0c commit 3f91572
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 11 deletions.
6 changes: 3 additions & 3 deletions src/rust/uisp_integration/src/strategies/full/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,6 @@ pub async fn build_full_network(
// Do Link Squashing
squash_single_aps(&mut sites)?;

// Build Path Weights
walk_tree_for_routing(&mut sites, &root_site, &routing_overrides)?;

// Apply bandwidth overrides
apply_bandwidth_overrides(&mut sites, &bandwidth_overrides);

Expand All @@ -140,6 +137,9 @@ pub async fn build_full_network(
// Squash any sites that are in the squash list
squash_squashed_sites(&mut sites, config.clone(), &root_site)?;

// Build Path Weights
walk_tree_for_routing(config.clone(), &mut sites, &root_site, &routing_overrides)?;

// Print Sites
if let Some(root_idx) = sites.iter().position(|s| s.name == root_site) {
// Issue No Parent Warnings
Expand Down
12 changes: 12 additions & 0 deletions src/rust/uisp_integration/src/strategies/full/routes_override.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use csv::ReaderBuilder;
use lqos_config::Config;
use serde::{Deserialize, Serialize};
use std::path::Path;
use std::sync::Arc;
use tracing::{error, info};

/// Represents a route override in the integrationUISProutes.csv file.
Expand Down Expand Up @@ -82,3 +83,14 @@ pub fn get_route_overrides(config: &Config) -> Result<Vec<RouteOverride>, UispIn
Ok(Vec::new())
}
}

pub fn write_routing_overrides_template(config: Arc<Config>, natural_routes: &[RouteOverride]) -> anyhow::Result<()> {
let file_path = Path::new(&config.lqos_directory).join("integrationUISProutes.template.csv");
let mut writer = csv::Writer::from_path(file_path)?;
writer.write_record(&["From Site", "To Site", "Cost"])?;
for route in natural_routes {
writer.write_record(&[&route.from_site, &route.to_site, &route.cost.to_string()])?;
}
writer.flush()?;
Ok(())
}
27 changes: 21 additions & 6 deletions src/rust/uisp_integration/src/strategies/full/tree_walk.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use std::io::Write;
use std::sync::Arc;
use lqos_config::Config;
use crate::errors::UispIntegrationError;
use crate::strategies::full::routes_override::RouteOverride;
use crate::strategies::full::routes_override::{write_routing_overrides_template, RouteOverride};
use crate::uisp_types::{UispSite, UispSiteType};

/// Walks the tree to determine the best route for each site
Expand All @@ -12,22 +14,29 @@ use crate::uisp_types::{UispSite, UispSiteType};
/// * `root_site` - The name of the root site
/// * `overrides` - The list of route overrides
pub fn walk_tree_for_routing(
config: Arc<Config>,
sites: &mut Vec<UispSite>,
root_site: &str,
overrides: &Vec<RouteOverride>,
) -> Result<(), UispIntegrationError> {
if let Some(root_idx) = sites.iter().position(|s| s.name == root_site) {
let mut visited = std::collections::HashSet::new();
let current_node = root_idx;
let mut dot_graph = "digraph G {\n graph [ ranksep=2.0 overlap=false ]".to_string();
walk_node(current_node, 10, sites, &mut visited, overrides, &mut dot_graph);
let mut natural_weights: Vec<RouteOverride> = Vec::new();
let mut dot_graph = "digraph G {\n graph [ ranksep=2.0 overlap=false ]\n".to_string();
walk_node(current_node, 10, sites, &mut visited, overrides, &mut dot_graph, &mut natural_weights);
dot_graph.push_str("}\n");
{
let graph_file = std::fs::File::create("graph.dot");
if let Ok(mut file) = graph_file {
let _ = file.write_all(dot_graph.as_bytes());
}
}
if let Err(e) = write_routing_overrides_template(config, &natural_weights) {
tracing::error!("Unable to write routing overrides template: {:?}", e);
} else {
tracing::info!("Wrote routing overrides template");
}
} else {
tracing::error!("Unable to build a path-weights graph because I can't find the root node");
return Err(UispIntegrationError::NoRootSite);
Expand All @@ -52,6 +61,7 @@ fn walk_node(
visited: &mut std::collections::HashSet<usize>,
overrides: &Vec<RouteOverride>,
dot_graph: &mut String,
natural_weights: &mut Vec<RouteOverride>,
) {
if visited.contains(&idx) {
return;
Expand All @@ -61,9 +71,14 @@ fn walk_node(
if sites[i].parent_indices.contains(&idx) {
let from = sites[i].name.clone();
let to = sites[idx].name.clone();
if sites[idx].site_type != UispSiteType::Client
if sites[idx].site_type != UispSiteType::Client && sites[i].site_type != UispSiteType::Client
{
dot_graph.push_str(&format!("\"{}\" [label=\"{}\"];\n", to, to));
dot_graph.push_str(&format!("\"{}\" -> \"{}\" [label=\"{}\"] \n", from, to, weight));
natural_weights.push(RouteOverride {
from_site: from.clone(),
to_site: to.clone(),
cost: weight,
});
}
if let Some(route_override) = overrides
.iter()
Expand All @@ -74,7 +89,7 @@ fn walk_node(
} else {
sites[i].route_weights.push((idx, weight));
}
walk_node(i, weight + 10, sites, visited, overrides, dot_graph);
walk_node(i, weight + 10, sites, visited, overrides, dot_graph, natural_weights);
}
}
}
4 changes: 2 additions & 2 deletions src/rust/uisp_integration/src/uisp_types/uisp_data_link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ impl UispDataLink {
let mut from_site_id = String::new();
let mut to_site_id = String::new();
let mut to_site_name = String::new();
let from_site_name = String::new();
let mut from_site_name = String::new();

// Obvious Site Links
if let Some(from_site) = &value.from.site {
from_site_id = from_site.identification.id.clone();
to_site_id = from_site.identification.name.clone();
from_site_name = from_site.identification.name.clone();
}
if let Some(to_site) = &value.to.site {
to_site_id = to_site.identification.id.clone();
Expand Down

0 comments on commit 3f91572

Please sign in to comment.