static IEnumerable <Destination> FindDestinations(Router root, RouterMetadata metadata, Blueprint map, List <Site> visitedSites) { var connectedSites = map.Sites.Where(s => s.Routers.Any(r => r.Name == root.Name)); foreach (var site in connectedSites) { if (visitedSites.Contains(site)) { continue; } visitedSites.Add(site); foreach (var endpoint in site.Endpoints) { yield return(new Destination(endpoint, site.Name)); } var nearbyGateways = site.Routers.Where(r => r.Name != metadata.Name); foreach (var router in nearbyGateways) { var furtherDestinations = FindDestinations(router, metadata, map, visitedSites); foreach (var furtherDestination in furtherDestinations) { yield return(furtherDestination); } } } }
public Task Start(RouterMetadata metadata) { blueprintAccess = accessConfiguration.Create(); return(blueprintAccess.Start(map => { RouteTable = BuildRouteTable(metadata, map); }, ex => { logger.Error("Error while refreshing system map.", ex); })); }
internal static RouteTable BuildRouteTable(RouterMetadata metadata, Blueprint map) { logger.Debug($"Building routing table for {metadata.Name}."); var table = new RouteTable(); var directlyConnectedSites = map.Sites.Where(s => s.Routers.Any(r => r.Name == metadata.Name)).ToList(); var endpointCardinality = map.Sites.SelectMany(s => s.Endpoints, (site, endpoint) => new { site, endpoint }).GroupBy(x => x.endpoint).ToDictionary(g => g.Key, g => g.Count() > 1); foreach (var iface in metadata.Interfaces) { var site = FindSiteConnectedToInterface(map, metadata.Name, iface); foreach (var endpoint in site.Endpoints) { if (endpointCardinality[endpoint]) { table.AddRoute((i, d) => i != iface && d.Endpoint == endpoint && d.Site == site.Name, $"Interface <> {iface} AND Endpoint = {endpoint} AND Site = {site.Name}", null, iface); } else { table.AddRoute((i, d) => i != iface && d.Endpoint == endpoint, $"Interface <> {iface} AND Endpoint = {endpoint}", null, iface); } } var nearbyGateways = site.Routers.Where(r => r.Name != metadata.Name); foreach (var gateway in nearbyGateways) { var destinations = FindDestinations(gateway, metadata, map, new List <Site>(directlyConnectedSites)).ToArray(); foreach (var destination in destinations) { if (endpointCardinality[destination.Endpoint]) { table.AddRoute((i, d) => i != gateway.Interface && d.Endpoint == destination.Endpoint && d.Site == destination.Site, $"Interface <> {gateway.Interface} AND Endpoint = {destination.Endpoint} AND Site = {destination.Site}", gateway.Name, iface); } else { table.AddRoute((i, d) => i != gateway.Interface && d.Endpoint == destination.Endpoint, $"Interface <> {gateway.Interface} AND Endpoint = {destination.Endpoint}", gateway.Name, iface); } } } } return(table); }