本文主要是介绍Floodlight源码阅读之网络拓扑,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
在上一篇文章中介绍Floodlight怎样做拓扑发现,这篇文章介绍一下网络拓扑是怎样形成的。TopologyManager这个类负责网络拓扑的产生。这个类首先实现了IFloodlightModule这个接口,是Floodlight的一个模块。其实是实现了ILinkDiscoveryListener用于监听网络中链路的变化;还实现了IOFMessageListener用于接收和处理网络包。
和其他的Floodlight模块一样,首先看启动方法startup。
@Overridepublic void startUp(FloodlightModuleContext context) {clearCurrentTopology();// Initialize role to floodlight provider role.this.role = floodlightProviderService.getRole();ScheduledExecutorService ses = threadPoolService.getScheduledExecutor();newInstanceTask = new SingletonTask(ses, new UpdateTopologyWorker());if (role != HARole.STANDBY) {newInstanceTask.reschedule(TOPOLOGY_COMPUTE_INTERVAL_MS, TimeUnit.MILLISECONDS);}linkDiscoveryService.addListener(this);floodlightProviderService.addOFMessageListener(OFType.PACKET_IN, this);floodlightProviderService.addHAListener(this.haListener);addRestletRoutable();}
在这个启动方法中第一行就是清理拓扑
/*** Clears the current topology. Note that this does NOT* send out updates.*/public void clearCurrentTopology() {this.clear();linksUpdated = true;dtLinksUpdated = true;tunnelPortsUpdated = true;createNewInstance("startup");lastUpdateTime = new Date();}
clear方法清理所以内存中保存的节点链路拓扑信息。
public void clear() {switchPorts.clear();tunnelPorts.clear();switchPortLinks.clear();portBroadcastDomainLinks.clear();directLinks.clear();}
关于这个nosql内存数据库下一章讲解。
当清理完数据后开始创建新的拓扑
/*** This function computes a new topology instance.* It ignores links connected to all broadcast domain ports* and tunnel ports. The method returns if a new instance of* topology was created or not.*/protected boolean createNewInstance(String reason) {Set<NodePortTuple> blockedPorts = new HashSet<NodePortTuple>();if (!linksUpdated) return false;Map<NodePortTuple, Set<Link>> openflowLinks;openflowLinks =new HashMap<NodePortTuple, Set<Link>>();Set<NodePortTuple> nptList = switchPortLinks.keySet();if (nptList != null) {for (NodePortTuple npt : nptList) {Set<Link> linkSet = switchPortLinks.get(npt);if (linkSet == null) continue;openflowLinks.put(npt, new HashSet<Link>(linkSet));}}// Identify all broadcast domain ports.// Mark any port that has inconsistent set of links// as broadcast domain ports as well.Set<NodePortTuple> broadcastDomainPorts =identifyBroadcastDomainPorts();// Remove all links incident on broadcast domain ports.for (NodePortTuple npt : broadcastDomainPorts) {if (switchPortLinks.get(npt) == null) continue;for (Link link : switchPortLinks.get(npt)) {removeLinkFromStructure(openflowLinks, link);}}// Remove all tunnel links.for (NodePortTuple npt : tunnelPorts) {if (switchPortLinks.get(npt) == null) continue;for (Link link : switchPortLinks.get(npt)) {removeLinkFromStructure(openflowLinks, link);}}//switchPorts contains only ports that are part of links. Calculation of broadcast ports needs set of all ports.Map<DatapathId, Set<OFPort>> allPorts = new HashMap<DatapathId, Set<OFPort>>();;for (DatapathId sw : switchPorts.keySet()) {allPorts.put(sw, this.getPorts(sw));}TopologyInstance nt = new TopologyInstance(switchPorts,blockedPorts,openflowLinks,broadcastDomainPorts,tunnelPorts,switchPortLinks,allPorts,portBroadcastDomainLinks);nt.compute();// We set the instances with and without tunnels to be identical.// If needed, we may compute them differently.currentInstance = nt;currentInstanceWithoutTunnels = nt;TopologyEventInfo topologyInfo =new TopologyEventInfo(0, nt.getClusters().size(),new HashMap<DatapathId, List<NodePortTuple>>(),0);eventCategory.newEventWithFlush(new TopologyEvent(reason, topologyInfo));return true;}
主要计算方法是nt.conpute()这个方法
这个方法有七步看代码如下
public void compute() {// Step 1: Compute clusters ignoring broadcast domain links// Create nodes for clusters in the higher level topology// Must ignore blocked links.identifyOpenflowDomains();// Step 1.1: Add links to clusters// Avoid adding blocked links to clustersaddLinksToOpenflowDomains();// Step 2. Compute shortest path trees in each cluster for// unicast routing. The trees are rooted at the destination.// Cost for tunnel links and direct links are the same.calculateShortestPathTreeInClusters();// Step 3. Compute broadcast tree in each cluster.// Cost for tunnel links are high to discourage use of// tunnel links. The cost is set to the number of nodes// in the cluster + 1, to use as minimum number of// clusters as possible.calculateBroadcastNodePortsInClusters();// Step 4. Compute e2e shortest path trees on entire topology for unicast routing.// The trees are rooted at the destination.// Cost for tunnel links and direct links are the same.calculateAllShortestPaths();// Compute the archipelagos (def: cluster of islands). An archipelago will// simply be a group of connected islands. Each archipelago will have its own// finiteBroadcastTree which will be randomly chosen.calculateArchipelagos();// Step 5. Compute broadcast tree for the whole topology (needed to avoid loops).// Cost for tunnel links are high to discourage use of// tunnel links. The cost is set to the number of nodes// in the cluster + 1, to use as minimum number of// clusters as possible.calculateAllBroadcastNodePorts();// Step 6. Compute set of ports for broadcasting. Edge ports are included.calculateBroadcastPortMap();// Step 7. print topology.printTopology();}
identifyOpenflowDomains这个方法通过深度优先遍历算法遍历拓扑节点
addLinksToOpenflowDomains添加集群直接的的link
calculateShortestPathTreeInClusters通过给链路添加权重在通clusterDijkstra最短路径算法计算拓扑最短路径
后面几个方法是整个网络的最短路径计算,详细部分文章后面一一解说
这篇关于Floodlight源码阅读之网络拓扑的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!