public Topology.MPLS.Topology LoadMPLSTopology() { Topology.MPLS.Topology topology = new Topology.MPLS.Topology(); foreach (var record in GetMPLSTopology()) { var path = record.Values["p"].As <IPath>(); Dictionary <long, string> nodeIPv4RouterIdentifiersByDatabaseId = new Dictionary <long, string>(); Dictionary <long, string> nodePCCByDatabaseId = new Dictionary <long, string>(); foreach (var node in path.Nodes) { string ipv4RouterIdentifier = TryGetNodePropertyAsString(node, "IPv4_Router_Identifier"); string pcc = TryGetNodePropertyAsString(node, "PCC"); if (!string.IsNullOrWhiteSpace(ipv4RouterIdentifier)) { nodeIPv4RouterIdentifiersByDatabaseId.Add(node.Id, ipv4RouterIdentifier); nodePCCByDatabaseId.Add(node.Id, pcc); Topology.Node.Node n = new Topology.Node.Node() { IPv4RouterIdentifier = TryGetNodePropertyAsString(node, "IPv4_Router_Identifier"), PCC = pcc, //NodeName = TryGetNodePropertyAsString(node, "Node_Name"), FirstSeen = TryGetNodeProperty <long>(node, "First_Seen"), //LastEvent = TryGetNodeProperty<long>(node, "Last_Event"), OperationalStatus = true }; n.IsPseudonode = false; n.NodeCost = 1; topology.Update(n); } } foreach (var lsp in path.Relationships) { var symbolicPathName = TryGetRelPropertyAsString(lsp, "Symbolic_Path_Name"); if (symbolicPathName.Contains("/")) { var hierarchicalSymbolicPathName = symbolicPathName.Split("/".ToCharArray()); Topology.MPLS.HierarchicalLabelSwitchedPath.HierarchicalLabelSwitchedPath parent = new Topology.MPLS.HierarchicalLabelSwitchedPath.HierarchicalLabelSwitchedPath(hierarchicalSymbolicPathName[0]) { IPv4TunnelSenderAddress = nodeIPv4RouterIdentifiersByDatabaseId[lsp.StartNodeId], IPv4TunnelEndpointAddress = nodeIPv4RouterIdentifiersByDatabaseId[lsp.EndNodeId] }; topology.Update(parent); Topology.MPLS.LabelSwitchedPath.LabelSwitchedPath child = new Topology.MPLS.LabelSwitchedPath.LabelSwitchedPath(parent.Id) { PCC = nodePCCByDatabaseId[lsp.StartNodeId], // Gets the PCC parameter from the StartNode instead of the LSP property, SHIFT PCEP listener is behind Docker Swarm NAT(PAT). IPv4TunnelSenderAddress = nodeIPv4RouterIdentifiersByDatabaseId[lsp.StartNodeId], IPv4TunnelEndpointAddress = nodeIPv4RouterIdentifiersByDatabaseId[lsp.EndNodeId], SymbolicPathName = symbolicPathName, TunnelIdentifier = TryGetRelPropertyAsString(lsp, "Tunnel_Identifier"), ExtendedTunnelIdentifier = TryGetRelPropertyAsString(lsp, "Extended_Tunnel_Identifier"), ExtendedTunnelIdentifierTunnelId = TryGetRelPropertyAsString(lsp, "Extended_Tunnel_Identifier_tunnel_id"), LspIdentifier = TryGetRelPropertyAsString(lsp, "LSP_Identifier"), ReservedBandwidth = TryGetRelProperty <long>(lsp, "Reserved_Bandwidth"), Administrative = TryGetRelProperty <bool>(lsp, "Administrative"), Delegate = TryGetRelProperty <bool>(lsp, "Delegate"), Operational = TryGetRelProperty <bool>(lsp, "Operational"), Remove = TryGetRelProperty <bool>(lsp, "Remove"), Sync = TryGetRelProperty <bool>(lsp, "Sync"), RecordRouteObject = TryGetRelPropertyAsArray <string>(lsp, "Record_Route_Object"), FirstSeen = TryGetRelProperty <long>(lsp, "First_Seen"), LastEvent = TryGetRelProperty <long>(lsp, "Last_Event") }; topology.Update(child); } else { Topology.MPLS.LabelSwitchedPath.LabelSwitchedPath l = new Topology.MPLS.LabelSwitchedPath.LabelSwitchedPath(null) { PCC = TryGetRelPropertyAsString(lsp, "PCC"), IPv4TunnelSenderAddress = nodeIPv4RouterIdentifiersByDatabaseId[lsp.StartNodeId], IPv4TunnelEndpointAddress = nodeIPv4RouterIdentifiersByDatabaseId[lsp.EndNodeId], SymbolicPathName = symbolicPathName, TunnelIdentifier = TryGetRelPropertyAsString(lsp, "Tunnel_Identifier"), ExtendedTunnelIdentifier = TryGetRelPropertyAsString(lsp, "Extended_Tunnel_Identifier"), ExtendedTunnelIdentifierTunnelId = TryGetRelPropertyAsString(lsp, "Extended_Tunnel_Identifier_tunnel_id"), LspIdentifier = TryGetRelPropertyAsString(lsp, "LSP_Identifier"), ReservedBandwidth = TryGetRelProperty <long>(lsp, "Reserved_Bandwidth"), Administrative = TryGetRelProperty <bool>(lsp, "Administrative"), Delegate = TryGetRelProperty <bool>(lsp, "Delegate"), Operational = TryGetRelProperty <bool>(lsp, "Operational"), Remove = TryGetRelProperty <bool>(lsp, "Remove"), Sync = TryGetRelProperty <bool>(lsp, "Sync"), RecordRouteObject = TryGetRelPropertyAsArray <string>(lsp, "Record_Route_Object"), FirstSeen = TryGetRelProperty <long>(lsp, "First_Seen"), LastEvent = TryGetRelProperty <long>(lsp, "Last_Event") }; topology.Update(l); } } } return(topology); }
public static void IntentProcessor(object result, Topology.MPLS.Topology mpls_topology, Topology.IGP.Topology igp_topology, string controller_uri, string controller_username, string controller_password, string ansible_tower_uri, string ansible_tower_username, string ansible_tower_password) { if (result != null) { if (result.GetType() == typeof(Topology.MPLS.HierarchicalLabelSwitchedPath.HierarchicalLabelSwitchedPath)) { Topology.MPLS.HierarchicalLabelSwitchedPath.HierarchicalLabelSwitchedPath hlsp = (Topology.MPLS.HierarchicalLabelSwitchedPath.HierarchicalLabelSwitchedPath)result; HLSP_Processor( hlsp, igp_topology, mpls_topology, controller_uri, controller_username, controller_password, ansible_tower_uri, ansible_tower_username, ansible_tower_password ); } else { if (result.GetType() == typeof(List <Topology.MPLS.HierarchicalLabelSwitchedPath.HierarchicalLabelSwitchedPath>)) { List <Topology.MPLS.HierarchicalLabelSwitchedPath.HierarchicalLabelSwitchedPath> hlsps = (List <Topology.MPLS.HierarchicalLabelSwitchedPath.HierarchicalLabelSwitchedPath>)result; HLSP_Processor( hlsps, igp_topology, mpls_topology, controller_uri, controller_username, controller_password, ansible_tower_uri, ansible_tower_username, ansible_tower_password ); } } } }
public Topology.MPLS.HierarchicalLabelSwitchedPath.HierarchicalLabelSwitchedPath ComputeModel(Topology.MPLS.HierarchicalLabelSwitchedPath.HierarchicalLabelSwitchedPath HierarchicalLabelSwitchedPath) { var source_node = this.Nodes.Where(n => n.Value.IPv4RouterIdentifier == HierarchicalLabelSwitchedPath.IPv4TunnelSenderAddress).SingleOrDefault(); var target_node = this.Nodes.Where(n => n.Value.IPv4RouterIdentifier == HierarchicalLabelSwitchedPath.IPv4TunnelEndpointAddress).SingleOrDefault(); if (source_node.Value != null && target_node.Value != null) { Tunnel tunnel = new Tunnel(); this.HoffmanPavley.Compute(source_node.Key, target_node.Key); List <Path> computedPaths = new List <Path>(); foreach (var path in this.HoffmanPavley.ComputedShortestPaths) { computedPaths.Add(new Path() { Hops = path.Select(h => h.Tag).ToList() }); } #region Return Optimisation if (HierarchicalLabelSwitchedPath.Children.Count <= computedPaths.Count) { for (int i = 0; i < HierarchicalLabelSwitchedPath.Children.Count; i++) { // Select only the actual next hops, for point to point and point to multipoint IGP links List <Topology.IGP.Link.Link> actual_next_hops = new List <Topology.IGP.Link.Link>(); for (int j = 0; j < computedPaths[i].Hops.Count; j++) { var current_hop = computedPaths[i].Hops[j]; var current_hop_target_node = this.Nodes[current_hop.TargetNode]; if (current_hop_target_node.IsPseudonode) { int k = j + 1; if (k < computedPaths[i].Hops.Count) { var next_hop = computedPaths[i].Hops[k]; actual_next_hops.Add(next_hop); j++; } } else { actual_next_hops.Add(current_hop); } } string[] computedHops = actual_next_hops.Select(h => h.IPv4InterfaceAddress).ToArray(); HierarchicalLabelSwitchedPath.Children[i].ComputedExplicitRouteObject = computedHops; } } else { for (int i = 0; i < computedPaths.Count; i++) { // Select only the actual next hops, for point to point and point to multipoint IGP links List <Topology.IGP.Link.Link> actual_next_hops = new List <Topology.IGP.Link.Link>(); for (int j = 0; j < computedPaths[i].Hops.Count; j++) { var current_hop = computedPaths[i].Hops[j]; var current_hop_target_node = this.Nodes[current_hop.TargetNode]; if (current_hop_target_node.IsPseudonode) { int k = j + 1; if (k < computedPaths[i].Hops.Count) { var next_hop = computedPaths[i].Hops[k]; actual_next_hops.Add(next_hop); j++; } } else { actual_next_hops.Add(current_hop); } } string[] computedHops = actual_next_hops.Select(h => h.IPv4InterfaceAddress).ToArray(); HierarchicalLabelSwitchedPath.Children[i].ComputedExplicitRouteObject = computedHops; } } #endregion } return(HierarchicalLabelSwitchedPath); }
private static void HLSP_Processor( Topology.MPLS.HierarchicalLabelSwitchedPath.HierarchicalLabelSwitchedPath hlsp, Topology.IGP.Topology igp_topology, Topology.MPLS.Topology mpls_topology, string controller_uri, string controller_username, string controller_password, string ansible_tower_uri, string ansible_tower_username, string ansible_tower_password) { if (string.IsNullOrWhiteSpace(hlsp.PCC)) { hlsp.PCC = hlsp.IPv4TunnelSenderAddress; } if (string.IsNullOrWhiteSpace(hlsp.AnsibleTowerHost)) { hlsp.AnsibleTowerHost = hlsp.PCC; } // Check if HLSP needs to be removed from configuration if (!hlsp.Delete) { // SDN Controller API Client Controllers.OpenDayLight.Nitrogen.ODLClient nitrogen = new Controllers.OpenDayLight.Nitrogen.ODLClient(controller_uri, controller_username, controller_password); // Check if HLSP does not exist or is marked as requiring a config update and launch Ansible Tower job to deploy (or update) base HLSP (including children) if ((mpls_topology.HierarchicalLabelSwitchedPaths.Where(h => h.SymbolicPathName == hlsp.SymbolicPathName).Count() == 0 || hlsp.UpdateConfiguration) && hlsp.Configure) { // Ansible Tower Client Ansible.TowerClient tc = new Ansible.TowerClient(ansible_tower_uri, ansible_tower_username, ansible_tower_password); var hlsps = new List <Topology.MPLS.HierarchicalLabelSwitchedPath.HierarchicalLabelSwitchedPath>(); hlsps.Add(hlsp); dynamic payload = new ExpandoObject(); payload.AnsibleTowerHost = hlsp.AnsibleTowerHost; payload.HierarchicalLabelSwitchedPaths = hlsps; var jobId = tc.LaunchJob(hlsp.AnsibleTowerJobTemplateId, payload, hlsp.AnsibleTowerHost); if (jobId != -1) { // Check if job is completed, max 60 times * 5 seconds = 5 min Console.WriteLine("Ansible Tower checking for job {0}.", jobId); var jobCompleted = tc.CheckJobCompleted(jobId); for (int i = 0; i < 60; i++) { Console.WriteLine("Ansible Tower checking for job {0}.", jobId); jobCompleted = tc.CheckJobCompleted(jobId); if (jobCompleted) { Console.WriteLine("Ansible Tower job {0} completed.", jobId); if (tc.CheckJobSuccessful(jobId)) { Console.WriteLine("Ansible Tower job {0} successful.", jobId); // Update paths through SDN controller foreach (var lsp in hlsp.Children) { if (lsp.Optimise) { nitrogen.UpdateLabelSwitchedPath(lsp); } } } else { Console.WriteLine("Ansible Tower job " + jobId + " failed."); } break; } System.Threading.Thread.Sleep(1000 * 5); } if (!jobCompleted) { Console.WriteLine("Timed out checking for Ansible Tower job " + jobId + ". Please check Ansible Tower logs."); } } else { Console.WriteLine("Unable to start Ansible Tower job."); } } else { // Update paths through SDN controller foreach (var lsp in hlsp.Children) { if (lsp.Optimise) { nitrogen.UpdateLabelSwitchedPath(lsp); } } } } else { if (hlsp.Configure) { // Ansible Tower Client Ansible.TowerClient tc = new Ansible.TowerClient(ansible_tower_uri, ansible_tower_username, ansible_tower_password); var hlsps = new List <Topology.MPLS.HierarchicalLabelSwitchedPath.HierarchicalLabelSwitchedPath>(); hlsps.Add(hlsp); dynamic payload = new ExpandoObject(); payload.AnsibleTowerHost = hlsp.AnsibleTowerHost; payload.HierarchicalLabelSwitchedPaths = hlsps; var jobId = tc.LaunchJob(hlsp.AnsibleTowerJobTemplateId, payload, hlsp.AnsibleTowerHost); if (jobId != -1) { // Check if job is completed, max 60 times * 5 seconds = 5 min Console.WriteLine("Ansible Tower checking for job {0}.", jobId); var jobCompleted = tc.CheckJobCompleted(jobId); for (int i = 0; i < 60; i++) { Console.WriteLine("Ansible Tower checking for job {0}.", jobId); jobCompleted = tc.CheckJobCompleted(jobId); if (jobCompleted) { Console.WriteLine("Ansible Tower job {0} completed.", jobId); if (tc.CheckJobSuccessful(jobId)) { Console.WriteLine("Ansible Tower job {0} successful.", jobId); } else { Console.WriteLine("Ansible Tower job " + jobId + " failed."); } break; } System.Threading.Thread.Sleep(1000 * 5); } if (!jobCompleted) { Console.WriteLine("Timed out checking for Ansible Tower job " + jobId + ". Please check Ansible Tower logs."); } } else { Console.WriteLine("Unable to start Ansible Tower job."); } } } }
public static void ValidatePathsUsingDijkstra(Topology.IGP.Topology igp_topology, Topology.MPLS.HierarchicalLabelSwitchedPath.HierarchicalLabelSwitchedPath hlsp) { Console.WriteLine("\n====Validating Paths====\n"); List <yggdrasil2.Topology.Node.Node> nodes_copy = igp_topology.Nodes.DeepClone(); List <yggdrasil2.Topology.IGP.Link.Link> links_copy = igp_topology.Links.DeepClone(); BidirectionalGraph <string, TaggedEdge <string, yggdrasil2.Topology.IGP.Link.Link> > graph = new BidirectionalGraph <string, TaggedEdge <string, yggdrasil2.Topology.IGP.Link.Link> >(); Dictionary <TaggedEdge <string, yggdrasil2.Topology.IGP.Link.Link>, double> cost = new Dictionary <TaggedEdge <string, yggdrasil2.Topology.IGP.Link.Link>, double>(); var start = nodes_copy.Where(n => n.IPv4RouterIdentifier == hlsp.IPv4TunnelSenderAddress).SingleOrDefault(); var end = nodes_copy.Where(n => n.IPv4RouterIdentifier == hlsp.IPv4TunnelEndpointAddress).SingleOrDefault(); if (start != null && end != null) { foreach (var lsp in hlsp.Children) { graph.Clear(); foreach (var node in nodes_copy) { graph.AddVertex(node.Id); } if (!start.IsPseudonode) // it will never be a pseudonode, get rid of this { var nodeLinks = links_copy.Where(l => l.SourceNode == start.Id).ToList(); foreach (var l in nodeLinks) { if (!graph.ContainsEdge(l.SourceNode, l.TargetNode)) { if (l.OperationalStatus) { var forwardEdge = new TaggedEdge <string, yggdrasil2.Topology.IGP.Link.Link>(l.SourceNode, l.TargetNode, l); graph.AddEdge(forwardEdge); cost.Add(forwardEdge, 1); } } } } foreach (var hop in lsp.ComputedExplicitRouteObject) { var link = links_copy.Where(l => l.IPv4InterfaceAddress == hop).SingleOrDefault(); if (link != null) { if (!graph.ContainsEdge(link.SourceNode, link.TargetNode)) { if (link.OperationalStatus) { var backwardEdge = new TaggedEdge <string, yggdrasil2.Topology.IGP.Link.Link>(link.TargetNode, link.SourceNode, link); graph.AddEdge(backwardEdge); cost.Add(backwardEdge, 1); } //var srcNode = nodes_copy.Where(n => n.IgpRouterIdentifier == link.SourceNode).SingleOrDefault(); var dstNode = nodes_copy.Where(n => n.IgpRouterIdentifier == link.TargetNode).SingleOrDefault(); //if (srcNode != null) //{ // if (srcNode.IsPseudonode) // { // var nodeLinks = links_copy.Where(l => l.TargetNode == srcNode.Id).ToList(); // foreach (var l in nodeLinks) // { // if (!graph.ContainsEdge(l.SourceNode, l.TargetNode)) // { // if (l.OperationalStatus) // { // var forwardEdge = new TaggedEdge<string, yggdrasil2.Topology.IGP.Link.Link>(l.SourceNode, l.TargetNode, l); // graph.AddEdge(forwardEdge); // cost.Add(forwardEdge, 1); // } // } // } // } //} if (dstNode != null) { if (dstNode.IsPseudonode) { var nodeLinks = links_copy.Where(l => l.TargetNode == dstNode.Id).ToList(); foreach (var l in nodeLinks) { if (!graph.ContainsEdge(l.SourceNode, l.TargetNode)) { if (l.OperationalStatus) { var forwardEdge = new TaggedEdge <string, yggdrasil2.Topology.IGP.Link.Link>(l.SourceNode, l.TargetNode, l); graph.AddEdge(forwardEdge); cost.Add(forwardEdge, 1); } } } } } } } } DijkstraShortestPathAlgorithm <string, TaggedEdge <string, yggdrasil2.Topology.IGP.Link.Link> > dijkstra = new DijkstraShortestPathAlgorithm <string, TaggedEdge <string, yggdrasil2.Topology.IGP.Link.Link> >(graph, AlgorithmExtensions.GetIndexer <TaggedEdge <string, yggdrasil2.Topology.IGP.Link.Link>, double>(cost)); dijkstra.Compute(start.Id); if (dijkstra.Distances.ContainsKey(end.Id) && dijkstra.Distances[end.Id] != double.MaxValue) { lsp.Feasible = true; Console.WriteLine("Path {0} is \u001b[32mFEASIBLE\u001b[0m.\n\t{1} is REACHABLE from {2} in {3} hops (includes pseudonodes).", lsp.SymbolicPathName, lsp.IPv4TunnelEndpointAddress, lsp.IPv4TunnelSenderAddress, dijkstra.Distances[end.Id]); } else { lsp.Feasible = false; Console.WriteLine("Path {0} is \u001b[31mNOT FEASIBLE\u001b[0m.\n\t{1} is UREACHABLE from {2}.", lsp.SymbolicPathName, lsp.IPv4TunnelEndpointAddress, lsp.IPv4TunnelSenderAddress); } } } }