diff --git a/src/main/java/net/floodlightcontroller/devicemanager/Device.java b/src/main/java/net/floodlightcontroller/devicemanager/Device.java index b3d8ade58f6002ecdd421184fd56aef8232374ce..d25d61963f67f17b0009f2d368f4584c10546b59 100755 --- a/src/main/java/net/floodlightcontroller/devicemanager/Device.java +++ b/src/main/java/net/floodlightcontroller/devicemanager/Device.java @@ -249,6 +249,14 @@ public class Device { } } + public void setOldAttachmentPoints(Collection<DeviceAttachmentPoint> attachmentPoints) { + this.oldAttachmentPoints = new ConcurrentHashMap<SwitchPortTuple, DeviceAttachmentPoint>(); + for (DeviceAttachmentPoint attachmentPoint: attachmentPoints) { + assert(attachmentPoint.getSwitchPort() != null); + addOldAttachmentPoint(attachmentPoint); + } + } + public Collection<DeviceAttachmentPoint> getOldAttachmentPoints() { return oldAttachmentPoints.values(); } @@ -258,7 +266,9 @@ public class Device { } public void addOldAttachmentPoint(DeviceAttachmentPoint attachmentPoint) { - oldAttachmentPoints.put(attachmentPoint.getSwitchPort(), attachmentPoint); + if (attachmentPoint != null) { + oldAttachmentPoints.put(attachmentPoint.getSwitchPort(), attachmentPoint); + } } public DeviceAttachmentPoint removeOldAttachmentPoint(DeviceAttachmentPoint attachmentPoint) { diff --git a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java index 3feb2a08614bd642c1d51cb41af7516e877bb586..282be992aa9865d8a2fed0db5baf377e238f48af 100755 --- a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java +++ b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java @@ -442,7 +442,7 @@ public class DeviceManagerImpl implements IDeviceManagerService, IOFMessageListe delFromIpv4AddressDeviceMap(nwAddr, d); dCopy.removeNetworkAddress(na); updateMaps(dCopy); - removeNetworkAddressFromStorage(d, na); + removeNetworkAddressFromStorage(d.getDlAddrString(), na); } } @@ -541,7 +541,9 @@ public class DeviceManagerImpl implements IDeviceManagerService, IOFMessageListe new Object[] {dap, dCopy.getAttachmentPoints().size(), d.getAttachmentPoints().size(), dCopy}); } - removeAttachmentPointFromStorage(d, dap); + removeAttachmentPointFromStorage(d.getDlAddrString(), + HexString.toHexString(dap.getSwitchPort().getSw().getId()), + dap.getSwitchPort().getPort().toString()); d = null; return true; } @@ -643,7 +645,7 @@ public class DeviceManagerImpl implements IDeviceManagerService, IOFMessageListe protected static int DEVICE_NA_MAX_AGE = 60 * 60 * 2; protected static int DEVICE_AP_MAX_AGE = 60 * 60 * 2; protected static long NBD_TO_BD_TIMEDIFF_MS = 300000; // 5 minutes - protected static long BD_TO_BD_TIMEDIFF_MS = 5000; // 0 seconds + protected static long BD_TO_BD_TIMEDIFF_MS = 5000; // 5 seconds // This the amount of time that we need for a device to move from // a non-broadcast domain port to a broadcast domain port. @@ -817,14 +819,17 @@ public class DeviceManagerImpl implements IDeviceManagerService, IOFMessageListe Ethernet eth = IFloodlightProviderService.bcStore.get( cntx, IFloodlightProviderService.CONTEXT_PI_PAYLOAD); - // If the packet in comes from a port that's not allowed by higher - // level topology, it should be dropped. An L2 bridge can result - // in this situation. + /** If a broadcast or multicast packetIn comes from a port that's not allowed by higher + * level topology, it should be dropped. + * If it is an unicast packetIn, let it go through. This is the case when the broadcast + * domain where the unicast packet originated learned the dst device on the wrong port. + * Hopefully, the response from dst device will correct the learning of the BD. + */ short pinPort = pi.getInPort(); long pinSw = sw.getId(); if (topology.isAllowed(pinSw, pinPort) == false) { if (eth.getEtherType() == Ethernet.TYPE_BDDP || - eth.isMulticast() == false) { + (eth.isBroadcast() == false && eth.isMulticast() == false)) { return Command.CONTINUE; } else { if (log.isDebugEnabled()) { @@ -841,14 +846,27 @@ public class DeviceManagerImpl implements IDeviceManagerService, IOFMessageListe match.loadFromPacket(pi.getPacketData(), pi.getInPort(), sw.getId()); // Add this packet-in to event history evHistPktIn(match); - if (log.isTraceEnabled()) - log.trace("Entering packet_in processing sw {}, port {}. {} --> {}, type {}", + if (log.isDebugEnabled()) + log.debug("Entering packet_in processing sw {}, port {}. {} --> {}, type {}", new Object[] { sw.getStringId(), pi.getInPort(), HexString.toHexString(match.getDataLayerSource()), HexString.toHexString(match.getDataLayerDestination()), match.getDataLayerType() }); + /** + * Drop all broadcast and multicast packets from not-allowed incoming broadcast ports + */ + if ((eth.isBroadcast() || eth.isMulticast()) && + !topology.isIncomingBroadcastAllowed(pinSw, pinPort)) { + if (log.isDebugEnabled()) { + log.debug("Drop broadcast/multicast packets with src {} from not-allowed incoming broadcast ports {} {}", + new Object[] {HexString.toHexString(eth.getSourceMACAddress()), + HexString.toHexString(pinSw), pinPort}); + } + return Command.STOP; + } + // Create attachment point/update network address if required SwitchPortTuple switchPort = new SwitchPortTuple(sw, pi.getInPort()); // Don't learn from internal port or invalid port @@ -895,57 +913,6 @@ public class DeviceManagerImpl implements IDeviceManagerService, IOFMessageListe // Copy-replace of device would be too expensive here device.setLastSeen(currentDate); updateDevice = device.shouldWriteLastSeenToStorage(); - - // If the attachment point moves from a non-broadcast domain - // port to a broadcast domain port too quickly, ignore learning - // the broadcast domain attachment point. - for ( DeviceAttachmentPoint oldDap : device.getAttachmentPoints() ) { - // if the two switches are in the same cluster - // and if currSw,CurrPort is not in broadcast domain - long currSw = oldDap.getSwitchPort().getSw().getId(); - short currPort = oldDap.getSwitchPort().getPort(); - long newSw = switchPort.getSw().getId(); - short newPort = switchPort.getPort(); - if ( (topology.getSwitchClusterId(currSw) == topology.getSwitchClusterId(newSw)) && - (topology.isBroadcastDomainPort(currSw, currPort) == false) && - (topology.isBroadcastDomainPort(newSw, newPort) == true)) { - long dt = currentDate.getTime() - - oldDap.getLastSeen().getTime() ; - if (dt < NBD_TO_BD_TIMEDIFF_MS) { - // if the packet was seen within the last 5 minutes, we should ignore. - // it should also ignore processing the packet. - if (log.isTraceEnabled()) { - log.trace("Surpressing too quick move of {} from non broadcast domain port {} {}" + - " to broadcast domain port {} {}. Last seen on non-BD {} sec ago", - new Object[] { HexString.toHexString(match.getDataLayerSource()), - oldDap.getSwitchPort().getSw().getStringId(), currPort, - switchPort.getSw().getStringId(), newPort, - dt/1000 } - ); - } - return Command.CONTINUE; - } - } else if ( (topology.getSwitchClusterId(currSw) == topology.getSwitchClusterId(newSw)) && - (topology.isBroadcastDomainPort(currSw, currPort) == true) && - (topology.isBroadcastDomainPort(newSw, newPort) == true)) { - long dt = currentDate.getTime() - - oldDap.getLastSeen().getTime() ; - if (dt < BD_TO_BD_TIMEDIFF_MS) { - // if the packet was seen within the last 5 seconds, we should ignore. - // it should also ignore processing the packet. - if (log.isTraceEnabled()) { - log.trace("Surpressing too quick move of {} from one broadcast domain port {} {}" + - " to another broadcast domain port {} {}. Last seen on BD {} sec ago", - new Object[] { HexString.toHexString(match.getDataLayerSource()), - oldDap.getSwitchPort().getSw().getStringId(), currPort, - switchPort.getSw().getStringId(), newPort, - dt/1000 } - ); - } - return Command.CONTINUE; - } - } - } if (isGratArp(eth)) { clearAttachmentPoints = true; @@ -956,6 +923,14 @@ public class DeviceManagerImpl implements IDeviceManagerService, IOFMessageListe updateAttachmentPointLastSeen = true; } else { newAttachmentPoint = true; + if ((eth.isBroadcast() || eth.isMulticast()) && + topology.isIncomingBroadcastAllowed(pinSw, pinPort) == false) { + if (log.isDebugEnabled()) { + log.debug("Port {} {} is not allowed for incoming broadcast packet", + HexString.toHexString(pinSw), pinPort); + } + newAttachmentPoint = false; + } } if (nwSrc != 0) { @@ -997,7 +972,7 @@ public class DeviceManagerImpl implements IDeviceManagerService, IOFMessageListe dCopy.setNetworkAddresses(namap.values()); this.devMgrMaps.updateMaps(dCopy); if (naOld !=null) - removeNetworkAddressFromStorage(dCopy, naOld); + removeNetworkAddressFromStorage(dCopy.getDlAddrString(), naOld); } } @@ -1019,6 +994,11 @@ public class DeviceManagerImpl implements IDeviceManagerService, IOFMessageListe if (attachmentPoint == null) { newAttachmentPoint = false; } else { + if (log.isDebugEnabled()) { + log.debug("Learned new AP for device {} at {}", + HexString.toHexString(nd.getDataLayerAddressAsLong()), + attachmentPoint); + } nd.addAttachmentPoint(attachmentPoint); evHistAttachmtPt(nd.getDataLayerAddressAsLong(), attachmentPoint.getSwitchPort(), @@ -1112,27 +1092,94 @@ public class DeviceManagerImpl implements IDeviceManagerService, IOFMessageListe // First, check if we have an existing attachment point DeviceAttachmentPoint curAttachmentPoint = null; - IOFSwitch newSwitch = swPort.getSw(); for (DeviceAttachmentPoint existingAttachmentPoint: device.getAttachmentPoints()) { - IOFSwitch existingSwitch = - existingAttachmentPoint.getSwitchPort().getSw(); - if ((newSwitch == existingSwitch) || ((topology != null) && - topology.inSameCluster(newSwitch.getId(), existingSwitch.getId()))) { - curAttachmentPoint = existingAttachmentPoint; - break; + // if the two switches are in the same cluster + long currSw = existingAttachmentPoint.getSwitchPort().getSw().getId(); + short currPort = existingAttachmentPoint.getSwitchPort().getPort(); + long newSw = swPort.getSw().getId(); + short newPort = swPort.getPort(); + long dt = currentDate.getTime() - existingAttachmentPoint.getLastSeen().getTime(); + if (topology.inSameCluster(currSw, newSw)) { + if ((topology.isBroadcastDomainPort(currSw, currPort) == false) && + (topology.isBroadcastDomainPort(newSw, newPort) == true)) { + if (dt < NBD_TO_BD_TIMEDIFF_MS) { + // if the packet was seen within the last 5 minutes, we should ignore. + // it should also ignore processing the packet. + if (log.isDebugEnabled()) { + log.debug("Surpressing too quick move of {} from non broadcast domain port {} {}" + + " to broadcast domain port {} {}. Last seen on non-BD {} sec ago", + new Object[] {device.getDlAddrString(), + existingAttachmentPoint.getSwitchPort().getSw().getStringId(), currPort, + swPort.getSw().getStringId(), newPort, + dt/1000 } + ); + } + return null; + } else { + if (log.isDebugEnabled()) { + log.debug("AP move of {} from non broadcast domain port {} {}" + + " to broadcast domain port {} {}. Last seen on BD {} sec ago", + new Object[] { device.getDlAddrString(), + existingAttachmentPoint.getSwitchPort().getSw().getStringId(), currPort, + swPort.getSw().getStringId(), newPort, + dt/1000 } + ); + } + curAttachmentPoint = existingAttachmentPoint; + break; + } + } else if ((topology.isBroadcastDomainPort(currSw, currPort) == true) && + (topology.isBroadcastDomainPort(newSw, newPort) == true)) { + if (topology.isInSameBroadcastDomain(currSw, currPort, newSw, newPort)) { + if (log.isDebugEnabled()) { + log.debug("new AP {} {} and current AP {} {} belong to the same broadcast domain", + new Object[] {HexString.toHexString(newSw), newPort, + HexString.toHexString(currSw), currPort}); + } + return null; + } + if (dt < BD_TO_BD_TIMEDIFF_MS) { + // if the packet was seen within the last 5 seconds, we should ignore. + // it should also ignore processing the packet. + if (log.isDebugEnabled()) { + log.debug("Surpressing too quick move of {} from one broadcast domain port {} {}" + + " to another broadcast domain port {} {}. Last seen on BD {} sec ago", + new Object[] {device.getDlAddrString(), + existingAttachmentPoint.getSwitchPort().getSw().getStringId(), currPort, + swPort.getSw().getStringId(), newPort, + dt/1000 } + ); + } + return null; + } else { + if (log.isDebugEnabled()) { + log.debug("AP move of {} from one broadcast domain port {} {}" + + " to another broadcast domain port {} {}. Last seen on BD {} sec ago", + new Object[] { device.getDlAddrString(), + existingAttachmentPoint.getSwitchPort().getSw().getStringId(), currPort, + swPort.getSw().getStringId(), newPort, + dt/1000 } + ); + } + curAttachmentPoint = existingAttachmentPoint; + break; + } + } else { + if (log.isDebugEnabled()) { + log.debug("AP move of {} from port {} {}" + + " to port {} {}. Last seen on BD {} sec ago", + new Object[] { device.getDlAddrString(), + existingAttachmentPoint.getSwitchPort().getSw().getStringId(), currPort, + swPort.getSw().getStringId(), newPort, + dt/1000 } + ); + } + curAttachmentPoint = existingAttachmentPoint; + break; + } } } - - if (curAttachmentPoint != null) { - Long curDPID = curAttachmentPoint.getSwitchPort().getSw().getId(); - Short curPort = curAttachmentPoint.getSwitchPort().getPort(); - boolean sameBD = - topology.isInSameBroadcastDomain(swPort.getSw().getId(), - swPort.getPort(), - curDPID, curPort); - if (sameBD) return null; - } // Do we have an old attachment point? DeviceAttachmentPoint attachmentPoint = @@ -1152,7 +1199,7 @@ public class DeviceManagerImpl implements IDeviceManagerService, IOFMessageListe log.info("Unblocking {} for device {}", attachmentPoint.getSwitchPort(), device); attachmentPoint.setBlocked(false); - evHistAttachmtPt(device.getDataLayerAddressAsLong(), swPort, + evHistAttachmtPt(device.getDataLayerAddressAsLong(), swPort, EvAction.UNBLOCKED, "packet-in after block timer expired"); } // Remove from old list @@ -1162,7 +1209,7 @@ public class DeviceManagerImpl implements IDeviceManagerService, IOFMessageListe // Update mappings devMgrMaps.addDevAttachmentPoint( device.getDataLayerAddressAsLong(), swPort, currentDate); - evHistAttachmtPt(device.getDataLayerAddressAsLong(), swPort, + evHistAttachmtPt(device.getDataLayerAddressAsLong(), swPort, EvAction.ADDED, "packet-in GNAP"); // If curAttachmentPoint exists, we mark it a conflict and may block it. @@ -1176,10 +1223,10 @@ public class DeviceManagerImpl implements IDeviceManagerService, IOFMessageListe curAttachmentPoint.setConflict(currentDate); if (curAttachmentPoint.isFlapping()) { curAttachmentPoint.setBlocked(true); - evHistAttachmtPt(device.getDataLayerAddressAsLong(), + evHistAttachmtPt(device.getDataLayerAddressAsLong(), curAttachmentPoint.getSwitchPort(), EvAction.BLOCKED, "Conflict"); - writeAttachmentPointToStorage(device, curAttachmentPoint, + writeAttachmentPointToStorage(device, curAttachmentPoint, currentDate); log.warn( "Device {}: flapping between {} and {}, block the latter", @@ -1187,24 +1234,27 @@ public class DeviceManagerImpl implements IDeviceManagerService, IOFMessageListe curAttachmentPoint.getSwitchPort()}); // Check if flapping is between the same switch port if (swPort.getSw().getId() == - curAttachmentPoint.getSwitchPort().getSw().getId() - && swPort.getPort() == - curAttachmentPoint.getSwitchPort().getPort()) { - log.warn("Fake flapping on port " + swPort.getPort() + - " between sw " + swPort.getSw() + " and " + - curAttachmentPoint.getSwitchPort().getSw()); - device.removeOldAttachmentPoint(curAttachmentPoint); - removeAttachmentPointFromStorage(device, - curAttachmentPoint); + curAttachmentPoint.getSwitchPort().getSw().getId() && + swPort.getPort() == + curAttachmentPoint.getSwitchPort().getPort()) { + log.warn("Fake flapping on port " + swPort.getPort() + + " between sw " + swPort.getSw() + " and " + + curAttachmentPoint.getSwitchPort().getSw()); + device.removeOldAttachmentPoint(curAttachmentPoint); + removeAttachmentPointFromStorage(device.getDlAddrString(), + HexString.toHexString(curAttachmentPoint.getSwitchPort().getSw().getId()), + curAttachmentPoint.getSwitchPort().getPort().toString()); } } else { - removeAttachmentPointFromStorage(device, curAttachmentPoint); - evHistAttachmtPt(device.getDataLayerAddressAsLong(), - curAttachmentPoint.getSwitchPort(), + removeAttachmentPointFromStorage(device.getDlAddrString(), + HexString.toHexString(curAttachmentPoint.getSwitchPort().getSw().getId()), + curAttachmentPoint.getSwitchPort().getPort().toString()); + evHistAttachmtPt(device.getDataLayerAddressAsLong(), + curAttachmentPoint.getSwitchPort(), EvAction.REMOVED, "Conflict"); } } - updateMoved(device, curAttachmentPoint.getSwitchPort(), + updateMoved(device, curAttachmentPoint.getSwitchPort(), attachmentPoint); if (log.isDebugEnabled()) { @@ -1343,12 +1393,18 @@ public class DeviceManagerImpl implements IDeviceManagerService, IOFMessageListe @Override public void addedSwitch(IOFSwitch sw) { + /** + * No point to restore the old APs on the switch since + * the hosts connecting to the switch will be discovered + * by ARP if anyone wants to talk to the hosts. + */ // Fix up attachment points related to the switch + /* lock.writeLock().lock(); try { Long swDpid = sw.getId(); List<PendingAttachmentPoint> papl = - devMgrMaps.switchUnresolvedAPMap.get(swDpid); + devMgrMaps.getSwitchUnresolvedAPMap().get(swDpid); if (papl != null) { for (PendingAttachmentPoint pap : papl) { Device d = devMgrMaps.getDeviceByDataLayerAddr(pap.mac); @@ -1361,11 +1417,11 @@ public class DeviceManagerImpl implements IDeviceManagerService, IOFMessageListe sw.getId(), pap.switchPort, EvAction.ADDED, "Switch Added"); } - devMgrMaps.switchUnresolvedAPMap.remove(swDpid); + devMgrMaps.getSwitchUnresolvedAPMap().remove(swDpid); } } finally { lock.writeLock().unlock(); - } + }*/ } @Override @@ -1522,7 +1578,7 @@ public class DeviceManagerImpl implements IDeviceManagerService, IOFMessageListe deviceUpdateTask.reschedule(10, TimeUnit.MILLISECONDS); } - private boolean isNewer(DeviceAttachmentPoint dap1, + protected boolean isNewer(DeviceAttachmentPoint dap1, DeviceAttachmentPoint dap2) { // dap 1 is newer than dap 2 if // (1) if dap 1 is a non-broadcast domain attachment point @@ -1539,25 +1595,25 @@ public class DeviceManagerImpl implements IDeviceManagerService, IOFMessageListe // dap2.lastseen SwitchPortTuple sp1, sp2; - boolean flag1, flag2; + boolean sp1IsBDPort, sp2IsBDPort; sp1 = dap1.getSwitchPort(); sp2 = dap2.getSwitchPort(); - flag1 = topology.isBroadcastDomainPort(sp1.getSw().getId(), + sp1IsBDPort = topology.isBroadcastDomainPort(sp1.getSw().getId(), sp1.getPort()); - flag2 = topology.isBroadcastDomainPort(sp2.getSw().getId(), + sp2IsBDPort = topology.isBroadcastDomainPort(sp2.getSw().getId(), sp2.getPort()); long ls1 = dap1.getLastSeen().getTime(); long ls2 = dap2.getLastSeen().getTime(); - if (flag1 == false) { - if (flag2 == false) { + if (sp1IsBDPort == false) { + if (sp2IsBDPort == false) { return (ls1 > ls2); } else { return (ls1 > (ls2 - NBD_TO_BD_TIMEDIFF_MS)); } } else { - if (flag2 == false) { + if (sp2IsBDPort == false) { return (ls1 > (ls2 + NBD_TO_BD_TIMEDIFF_MS)); } else { return ((ls1 > ls2 + BD_TO_BD_TIMEDIFF_MS) || @@ -1566,14 +1622,16 @@ public class DeviceManagerImpl implements IDeviceManagerService, IOFMessageListe } } /** - * Removes any attachment points that are in the same - * {@link net.floodlightcontroller.topology.SwitchCluster SwitchCluster} + * Removes any attachment points that are in the same + * {@link net.floodlightcontroller.topology.SwitchCluster SwitchCluster} * @param d The device to update the attachment points */ public void cleanupAttachmentPoints(Device d) { // The long here is the SwitchCluster ID - Map<Long, DeviceAttachmentPoint> map = + Map<Long, DeviceAttachmentPoint> tempAPMap = new HashMap<Long, DeviceAttachmentPoint>(); + Map<Long, DeviceAttachmentPoint> tempOldAPMap = + new HashMap<Long, DeviceAttachmentPoint>(); // Get only the latest DAPs into a map for (DeviceAttachmentPoint dap : d.getAttachmentPoints()) { @@ -1588,19 +1646,18 @@ public class DeviceManagerImpl implements IDeviceManagerService, IOFMessageListe if (topology.isAllowed(swid, port) == false) continue; - if (map.containsKey(clusterId)) { + if (tempAPMap.containsKey(clusterId)) { // We compare to see which one is newer, move attachment // point to "old" list. // They are removed after deleting from storage. - DeviceAttachmentPoint value = map.get(clusterId); - //if (dap.getLastSeen().after(value.getLastSeen())) { - if (isNewer(dap, map.get(clusterId))) { - map.put(clusterId, dap); - d.addOldAttachmentPoint(value); // on copy of device + DeviceAttachmentPoint existingDap = tempAPMap.get(clusterId); + if (isNewer(dap, existingDap)) { + tempAPMap.put(clusterId, dap); + tempOldAPMap.put(clusterId, existingDap); } } else { - map.put(clusterId, dap); + tempAPMap.put(clusterId, dap); } } } @@ -1608,7 +1665,8 @@ public class DeviceManagerImpl implements IDeviceManagerService, IOFMessageListe synchronized (d) { // Since the update below is happening on a copy of the device it // should not impact packetIn processing time due to lock contention - d.setAttachmentPoints(map.values()); + d.setAttachmentPoints(tempAPMap.values()); + d.setOldAttachmentPoints(tempOldAPMap.values()); } } @@ -1679,20 +1737,16 @@ public class DeviceManagerImpl implements IDeviceManagerService, IOFMessageListe // Storage Remove Methods // ********************** - protected void removeAttachmentPointFromStorage(Device device, - DeviceAttachmentPoint attachmentPoint) { + protected void removeAttachmentPointFromStorage(String deviceId, + String switchId, String port) { + String attachmentPointId = + deviceId + "|" + switchId + "|" + port; try { - String deviceId = device.getDlAddrString(); - SwitchPortTuple switchPort = attachmentPoint.getSwitchPort(); - String switchId = switchPort.getSw().getStringId(); - Short port = switchPort.getPort(); - String attachmentPointId = - deviceId + "|" + switchId + "|" + port.toString(); storageSource.deleteRowAsync( DEVICE_ATTACHMENT_POINT_TABLE_NAME, attachmentPointId); } catch (NullPointerException e) { - log.warn("Null ptr exception for device {} attach-point {}", - device, attachmentPoint); + log.warn("Null ptr exception for device {} on sw {} port {}", + new Object[] {deviceId, switchId, port}); } } @@ -1721,11 +1775,10 @@ public class DeviceManagerImpl implements IDeviceManagerService, IOFMessageListe networkAddress.lastSeenWrittenToStorage(currentDate); } - protected void removeNetworkAddressFromStorage(Device device, + protected void removeNetworkAddressFromStorage(String deviceId, DeviceNetworkAddress networkAddress) { - assert(device != null); + assert(deviceId != null); assert(networkAddress != null); - String deviceId = device.getDlAddrString(); String networkAddressString = IPv4.fromIPv4Address( networkAddress.getNetworkAddress()); String networkAddressId = deviceId + "|" + networkAddressString; @@ -1830,11 +1883,12 @@ public class DeviceManagerImpl implements IDeviceManagerService, IOFMessageListe long mac = HexString.toLong(macString); long swDpid = HexString.toLong(dpidString); IOFSwitch sw = floodlightProvider.getSwitches().get(swDpid); - Integer port = dapResultSet.getIntegerObject(PORT_COLUMN_NAME); + if (port == null || port > Short.MAX_VALUE) continue; if (sw == null) { // switch has not joined yet + removeAttachmentPointFromStorage(macString, dpidString, port.toString()); devMgrMaps.updateSwitchUnresolvedAPMap( swDpid, mac, port.shortValue(), lastSeen); } else { @@ -1945,9 +1999,11 @@ public class DeviceManagerImpl implements IDeviceManagerService, IOFMessageListe * @return the new device object since the device is immutable */ private Device removeAgedAttachmentPoints(Device device, Date currentDate) { - Collection<DeviceAttachmentPoint> aps = device.getAttachmentPoints(); + if (device == null) return null; long dlAddr = device.getDataLayerAddressAsLong(); + Collection<DeviceAttachmentPoint> aps = device.getAttachmentPoints(); + for (DeviceAttachmentPoint ap : aps) { int expire = ap.getExpire(); @@ -1956,6 +2012,7 @@ public class DeviceManagerImpl implements IDeviceManagerService, IOFMessageListe } Date agedBoundary = ageBoundaryDifference(currentDate, expire); if (ap.getLastSeen().before(agedBoundary)) { + log.debug("remove AP {} from device {}", ap, HexString.toHexString(dlAddr)); devMgrMaps.delDevAttachmentPoint(dlAddr, ap.getSwitchPort()); evHistAttachmtPt(device.getDataLayerAddressAsLong(), ap.getSwitchPort(), EvAction.REMOVED, @@ -1969,23 +2026,23 @@ public class DeviceManagerImpl implements IDeviceManagerService, IOFMessageListe /** * Age device entry based on an expiry associated with the device. */ - private void removeAgedDevices(Date currentDate) { + private void removeAgedDevices(Date currentDate) { Date deviceAgeBoundary = ageBoundaryDifference(currentDate, - DEVICE_MAX_AGE); + DEVICE_MAX_AGE); Collection<Device> deviceColl = devMgrMaps.getDevices(); for (Device device: deviceColl) { - device = removeAgedNetworkAddresses(device, currentDate); - device = removeAgedAttachmentPoints(device, currentDate); + device = removeAgedNetworkAddresses(device, currentDate); + device = removeAgedAttachmentPoints(device, currentDate); - if ((device.getAttachmentPoints().size() == 0) && - (device.getNetworkAddresses().size() == 0) && - (device.getLastSeen().before(deviceAgeBoundary))) { - delDevice(device); - } - } + if ((device.getAttachmentPoints().size() == 0) && + (device.getNetworkAddresses().size() == 0) && + (device.getLastSeen().before(deviceAgeBoundary))) { + delDevice(device); + } + } } - + protected static int DEVICE_AGING_TIMER= 60 * 15; // in seconds protected static final int DEVICE_AGING_TIMER_INTERVAL = 1; // in seconds @@ -2044,6 +2101,7 @@ public class DeviceManagerImpl implements IDeviceManagerService, IOFMessageListe while (maxIter > 0) { try { for (Device d: devMgrMaps.getDevicesOnASwitch(sw)) { + log.debug("Cleanup APs for device {}", HexString.toHexString(d.getDataLayerAddressAsLong())); Device dCopy = new Device(d); cleanupAttachmentPoints(dCopy); for (DeviceAttachmentPoint dap : @@ -2052,10 +2110,12 @@ public class DeviceManagerImpl implements IDeviceManagerService, IOFMessageListe // with recent activities if (dap.isInConflict() && !updatePortChannel) continue; - // Delete from memory after storage, + // Delete from memory after storage, // otherwise an exception will // leave stale attachment points on storage. - removeAttachmentPointFromStorage(dCopy, dap); + removeAttachmentPointFromStorage(dCopy.getDlAddrString(), + HexString.toHexString(dap.getSwitchPort().getSw().getId()), + dap.getSwitchPort().getPort().toString()); dCopy.removeOldAttachmentPoint(dap); } // Update the maps with the new device copy diff --git a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java b/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java index abd8d91565b97053067c76e7410760e9424ba72f..a15ec3001d1bd52dc32ae1c2aa8031def45d5ab0 100644 --- a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java +++ b/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java @@ -212,8 +212,8 @@ public class LinkDiscoveryManager if (topologyAware != null) { for (ILinkDiscoveryListener lda : linkDiscoveryAware) { // order maintained - if (log.isDebugEnabled()) { - log.debug("Dispatching link discovery update {} {} {} {} {}", + if (log.isTraceEnabled()) { + log.trace("Dispatching link discovery update {} {} {} {} {}", new Object[]{update.getOperation(), update.getSrc(), update.getSrcPort(), update.getDst(), update.getDstPort()}); @@ -454,8 +454,8 @@ public class LinkDiscoveryManager if (remoteSwitch == null) { // Ignore LLDPs not generated by Floodlight, or from a switch that has recently // disconnected, or from a switch connected to another Floodlight instance - if (log.isDebugEnabled()) { - log.debug("Received LLDP from remote switch not connected to the controller"); + if (log.isTraceEnabled()) { + log.trace("Received LLDP from remote switch not connected to the controller"); } return Command.STOP; } @@ -565,7 +565,6 @@ public class LinkDiscoveryManager updateOperation = UpdateOperation.ADD_OR_UPDATE; linkChanged = true; - log.debug("Added link {}", lt); // Add to event history evHistTopoLink(lt.getSrc().getSw().getId(), lt.getDst().getSw().getId(), diff --git a/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java b/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java index 0ce727b96f3e4a3a3a9a7614f8ddd18e1fa6434d..76e5078b00dc09b86ef4ff7717a56719e23c314f 100644 --- a/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java +++ b/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java @@ -228,9 +228,11 @@ public abstract class ForwardingBase implements IOFMessageListener, IDeviceManag try { counterStore.updatePktOutFMCounterStore(sw, fm); - log.debug("pushRoute flowmod sw={} inPort={} outPort={}", + if (log.isDebugEnabled()) { + log.debug("pushRoute flowmod sw={} inPort={} outPort={}", new Object[] { sw, fm.getMatch().getInputPort(), ((OFActionOutput)fm.getActions().get(0)).getPort() }); + } sw.write(fm, cntx); if (doFlush) { sw.flush(); diff --git a/src/main/java/net/floodlightcontroller/topology/ITopologyService.java b/src/main/java/net/floodlightcontroller/topology/ITopologyService.java index 138e90d89b1b002c4be56b9ef6dd1666987e7721..f2c95087d103ef44924e1a3f54acb01b9f9b4397 100644 --- a/src/main/java/net/floodlightcontroller/topology/ITopologyService.java +++ b/src/main/java/net/floodlightcontroller/topology/ITopologyService.java @@ -65,6 +65,17 @@ public interface ITopologyService extends IFloodlightService { short srcPort, long dst, short dstPort); + + /** + * If the src broadcast domain port is not allowed for incoming broadcast, + * this method provides the topologically equivalent incoming broadcast-allowed + * src port. + * @param src + * @param dst + * @return the allowed broadcast port + */ + public NodePortTuple getAllowedIncomingBroadcastPort(long src, + short srcPort); public boolean isIncomingBroadcastAllowed(long sw, short portId); diff --git a/src/main/java/net/floodlightcontroller/topology/NodePortTuple.java b/src/main/java/net/floodlightcontroller/topology/NodePortTuple.java index 67cebeaaf1f04ac8d5b67d9b4e4cec6c63777648..a2fc7dfeae65495efbdcb0ed91c7bd230dff2740 100644 --- a/src/main/java/net/floodlightcontroller/topology/NodePortTuple.java +++ b/src/main/java/net/floodlightcontroller/topology/NodePortTuple.java @@ -1,5 +1,7 @@ package net.floodlightcontroller.topology; +import org.openflow.util.HexString; + public class NodePortTuple { protected long nodeId; protected short portId; @@ -23,7 +25,7 @@ public class NodePortTuple { } public String toString() { - return "[id=" + new Long(nodeId) + ", port=" + new Short(portId) + "]"; + return "[id=" + HexString.toHexString(nodeId) + ", port=" + new Short(portId) + "]"; } @Override diff --git a/src/main/java/net/floodlightcontroller/topology/TopologyInstance.java b/src/main/java/net/floodlightcontroller/topology/TopologyInstance.java index 8c191ed261bbb68835a1caec97be9640ffba335c..061b96e4fe6ebd5af0bc6700124643b444da9330 100644 --- a/src/main/java/net/floodlightcontroller/topology/TopologyInstance.java +++ b/src/main/java/net/floodlightcontroller/topology/TopologyInstance.java @@ -581,4 +581,10 @@ public class TopologyInstance { // TODO Auto-generated method stub return null; } + + public NodePortTuple + getAllowedIncomingBroadcastPort(long src, short srcPort) { + // TODO Auto-generated method stub + return null; + } } diff --git a/src/main/java/net/floodlightcontroller/topology/TopologyManager.java b/src/main/java/net/floodlightcontroller/topology/TopologyManager.java index 4cd19effdb828a60ed806eedbb75cb210aab5db4..247e63f198ae959a1212c99e1ba405c07eb0daaf 100644 --- a/src/main/java/net/floodlightcontroller/topology/TopologyManager.java +++ b/src/main/java/net/floodlightcontroller/topology/TopologyManager.java @@ -379,6 +379,12 @@ IRoutingService, ILinkDiscoveryListener { dst,dstPort); } + @Override + public NodePortTuple getAllowedIncomingBroadcastPort(long src, + short srcPort) { + return currentInstance.getAllowedIncomingBroadcastPort(src,srcPort); + } + @Override public boolean isIncomingBroadcastAllowed(long sw, short portId) { return currentInstance.isIncomingBroadcastAllowedOnSwitchPort(sw, portId); diff --git a/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java b/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java index ac0f5b025d492358b87e216af655901ab1e29004..8d241604edeac7f1c6cab16ef63fec2a15205920 100644 --- a/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java +++ b/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java @@ -191,9 +191,101 @@ public class DeviceManagerImplTest extends FloodlightTestCase { assertEquals((int)2, d.getAttachmentPoints().size()); } + @Test + public void testIsNewer() throws Exception { + long delta = 100; + + IOFSwitch bdsw1 = createMock(IOFSwitch.class); + IOFSwitch bdsw2 = createMock(IOFSwitch.class); + IOFSwitch nonbdsw1 = createMock(IOFSwitch.class); + IOFSwitch nonbdsw2 = createMock(IOFSwitch.class); + expect(bdsw1.getId()).andReturn(1L).anyTimes(); + expect(bdsw2.getId()).andReturn(2L).anyTimes(); + expect(nonbdsw1.getId()).andReturn(3L).anyTimes(); + expect(nonbdsw2.getId()).andReturn(4L).anyTimes(); + + ITopologyService mockTopology = createMock(ITopologyService.class); + SwitchPortTuple bdspt1 = new SwitchPortTuple(bdsw1, (short)1); + SwitchPortTuple bdspt2 = new SwitchPortTuple(bdsw2, (short)1); + SwitchPortTuple nonbdspt1 = new SwitchPortTuple(nonbdsw1, (short)1); + SwitchPortTuple nonbdspt2 = new SwitchPortTuple(nonbdsw2, (short)1); + deviceManager.setTopology(mockTopology); + expect(mockTopology.isBroadcastDomainPort(1L, (short)1)).andReturn(true).anyTimes(); + expect(mockTopology.isBroadcastDomainPort(2L, (short)1)).andReturn(true).anyTimes(); + expect(mockTopology.isBroadcastDomainPort(3L, (short)1)).andReturn(false).anyTimes(); + expect(mockTopology.isBroadcastDomainPort(4L, (short)1)).andReturn(false).anyTimes(); + + // Two BD APs comparison + Date lastSeen_bd1 = new Date(); + Date lastSeen_bd2 = new Date(lastSeen_bd1.getTime() + DeviceManagerImpl.BD_TO_BD_TIMEDIFF_MS + delta); + DeviceAttachmentPoint dap_bd1 = new DeviceAttachmentPoint(bdspt1, lastSeen_bd1); + DeviceAttachmentPoint dap_bd2 = new DeviceAttachmentPoint(bdspt2, lastSeen_bd2); + + Date lastSeen_bd3 = new Date(); + Date lastSeen_bd4 = new Date(lastSeen_bd3.getTime() - DeviceManagerImpl.BD_TO_BD_TIMEDIFF_MS + delta); + DeviceAttachmentPoint dap_bd3 = new DeviceAttachmentPoint(bdspt1, lastSeen_bd3); + DeviceAttachmentPoint dap_bd4 = new DeviceAttachmentPoint(bdspt2, lastSeen_bd4); + + // Two non-BD APs comparison + Date lastSeen_nonbd1 = new Date(); + Date lastSeen_nonbd2 = new Date(lastSeen_nonbd1.getTime() + delta); + DeviceAttachmentPoint dap_nonbd1 = new DeviceAttachmentPoint(nonbdspt1, lastSeen_nonbd1); + DeviceAttachmentPoint dap_nonbd2 = new DeviceAttachmentPoint(nonbdspt2, lastSeen_nonbd2); + + Date lastSeen_nonbd3 = new Date(); + Date lastSeen_nonbd4 = new Date(lastSeen_bd3.getTime() - delta); + DeviceAttachmentPoint dap_nonbd3 = new DeviceAttachmentPoint(nonbdspt1, lastSeen_nonbd3); + DeviceAttachmentPoint dap_nonbd4 = new DeviceAttachmentPoint(nonbdspt2, lastSeen_nonbd4); + + // BD and non-BD APs comparison + Date lastSeen_bd5 = new Date(); + Date lastSeen_nonbd5 = new Date(lastSeen_bd3.getTime() - DeviceManagerImpl.NBD_TO_BD_TIMEDIFF_MS + delta); + DeviceAttachmentPoint dap_bd5 = new DeviceAttachmentPoint(bdspt1, lastSeen_bd5); + DeviceAttachmentPoint dap_nonbd5 = new DeviceAttachmentPoint(bdspt2, lastSeen_nonbd5); + + Date lastSeen_bd6 = new Date(); + Date lastSeen_nonbd6 = new Date(lastSeen_bd6.getTime() + DeviceManagerImpl.NBD_TO_BD_TIMEDIFF_MS + delta); + DeviceAttachmentPoint dap_bd6 = new DeviceAttachmentPoint(nonbdspt1, lastSeen_bd6); + DeviceAttachmentPoint dap_nonbd6 = new DeviceAttachmentPoint(nonbdspt2, lastSeen_nonbd6); + + replay(bdsw1, bdsw2, nonbdsw1, nonbdsw2, mockTopology); + + boolean testbd1_2 = deviceManager.isNewer(dap_bd1, dap_bd2); + boolean testbd2_1 = deviceManager.isNewer(dap_bd2, dap_bd1); + boolean testbd3_4 = deviceManager.isNewer(dap_bd3, dap_bd4); + boolean testbd4_3 = deviceManager.isNewer(dap_bd4, dap_bd3); + + boolean testnonbd1_2 = deviceManager.isNewer(dap_nonbd1, dap_nonbd2); + boolean testnonbd2_1 = deviceManager.isNewer(dap_nonbd2, dap_nonbd1); + boolean testnonbd3_4 = deviceManager.isNewer(dap_nonbd3, dap_nonbd4); + boolean testnonbd4_3 = deviceManager.isNewer(dap_nonbd4, dap_nonbd3); + + boolean testbdnonbd5_5 = deviceManager.isNewer(dap_bd5, dap_nonbd5); + boolean testnonbdbd5_5 = deviceManager.isNewer(dap_nonbd5, dap_bd5); + boolean testbdnonbd6_6 = deviceManager.isNewer(dap_bd6, dap_nonbd6); + boolean testnonbdbd6_6 = deviceManager.isNewer(dap_nonbd6, dap_bd6); + + verify(bdsw1, bdsw2, nonbdsw1, nonbdsw2, mockTopology); + + assertFalse(testbd1_2); + assertTrue(testbd2_1); + assertFalse(testbd3_4); + assertTrue(testbd4_3); + + assertFalse(testnonbd1_2); + assertTrue(testnonbd2_1); + assertTrue(testnonbd3_4); + assertFalse(testnonbd4_3); + + assertTrue(testbdnonbd5_5); + assertFalse(testnonbdbd5_5); + assertFalse(testbdnonbd6_6); + assertTrue(testnonbdbd6_6); + } + @Test public void testDeviceAging() throws Exception { - + byte[] dataLayerSource = ((Ethernet)this.testARPReplyPacket_1).getSourceMACAddress(); // Mock up our expected behavior @@ -203,34 +295,34 @@ public class DeviceManagerImplTest extends FloodlightTestCase { IOFSwitch mockSwitch2 = createMock(IOFSwitch.class); ITopologyService mockTopology = createMock(ITopologyService.class); expect(mockTopology.isInternal(1L, (short)1)).andReturn(false); - expect(mockTopology.getSwitchClusterId(1L)).andReturn(1L).atLeastOnce(); deviceManager.setTopology(mockTopology); - // reduce the aging period + + // reduce the aging period to a few seconds DeviceManagerImpl.DEVICE_AGING_TIMER = 2; DeviceManagerImpl.DEVICE_AP_MAX_AGE = 1; DeviceManagerImpl.DEVICE_NA_MAX_AGE = 1; DeviceManagerImpl.DEVICE_MAX_AGE = 3; Date currentDate = new Date(); - + // build our expected Device Device device = new Device(); device.setDataLayerAddress(dataLayerSource); device.addAttachmentPoint(new SwitchPortTuple(mockSwitch1, (short)1), currentDate); Integer ipaddr = IPv4.toIPv4Address("192.168.1.1"); device.addNetworkAddress(ipaddr, currentDate); + expect(mockSwitch2.getId()).andReturn(2L).anyTimes(); expect(mockSwitch2.getStringId()).andReturn("00:00:00:00:00:00:00:02").anyTimes(); expect(mockTopology.isInternal(2L, (short)2)).andReturn(false); - expect(mockTopology.inSameCluster(2L, 1L)).andReturn(false); - expect(mockTopology.getSwitchClusterId(2L)).andReturn(2L).atLeastOnce(); + expect(mockTopology.inSameCluster(1L, 2L)).andReturn(false).atLeastOnce(); expect(mockTopology.isAllowed(EasyMock.anyLong(), EasyMock.anyShort())).andReturn(true).anyTimes(); - + // Start recording the replay on the mocks replay(mockSwitch1, mockSwitch2, mockTopology); // Get the listener and trigger the packet in mockFloodlightProvider.dispatchMessage(mockSwitch1, this.packetIn_1); - + // Get the listener and trigger the packet in mockFloodlightProvider.dispatchMessage(mockSwitch2, this.packetIn_3.setInPort((short)2)); @@ -241,36 +333,36 @@ public class DeviceManagerImplTest extends FloodlightTestCase { assertEquals(device, rdevice); assertEquals(2, rdevice.getAttachmentPoints().size()); assertEquals(2, rdevice.getNetworkAddresses().size()); - + // Sleep to make sure the aging thread has run Thread.sleep((DeviceManagerImpl.DEVICE_AGING_TIMER + DeviceManagerImpl.DEVICE_AGING_TIMER_INTERVAL)*1000); - + rdevice = deviceManager.getDeviceByDataLayerAddress(dataLayerSource); assertEquals(0, rdevice.getAttachmentPoints().size()); assertEquals(0, rdevice.getNetworkAddresses().size()); - + // Make sure the device's AP and NA were removed from storage deviceManager.readAllDeviceStateFromStorage(); rdevice = deviceManager.getDeviceByDataLayerAddress(dataLayerSource); assertEquals(0, rdevice.getAttachmentPoints().size()); assertEquals(0, rdevice.getNetworkAddresses().size()); - + // Sleep 4 more seconds to allow device aging thread to run Thread.sleep(DeviceManagerImpl.DEVICE_MAX_AGE*1000); assertNull(deviceManager.getDeviceByDataLayerAddress(dataLayerSource)); - + // Make sure the device's AP and NA were removed from storage deviceManager.readAllDeviceStateFromStorage(); assertNull(deviceManager.getDeviceByDataLayerAddress(dataLayerSource)); - + // Reset the device cache deviceManager.clearAllDeviceStateFromMemory(); } - + @Test public void testDeviceDiscover() throws Exception { - + byte[] dataLayerSource = ((Ethernet)this.testARPReplyPacket_1).getSourceMACAddress(); // Mock up our expected behavior @@ -282,7 +374,7 @@ public class DeviceManagerImplTest extends FloodlightTestCase { deviceManager.setTopology(mockTopology); Date currentDate = new Date(); - + // build our expected Device Device device = new Device(); device.setDataLayerAddress(dataLayerSource); @@ -307,7 +399,7 @@ public class DeviceManagerImplTest extends FloodlightTestCase { // move the port on this device device.addAttachmentPoint(new SwitchPortTuple(mockSwitch, (short)2), currentDate); - + reset(mockSwitch, mockTopology); expect(mockSwitch.getId()).andReturn(2L).anyTimes(); expect(mockSwitch.getStringId()).andReturn("00:00:00:00:00:00:00:02").anyTimes(); @@ -316,7 +408,7 @@ public class DeviceManagerImplTest extends FloodlightTestCase { assertEquals(1, deviceManager.getDeviceByIPv4Address(ipaddr).getAttachmentPoints().size()); deviceManager.invalidateDeviceAPsByIPv4Address(ipaddr); assertEquals(0, deviceManager.getDeviceByIPv4Address(ipaddr).getAttachmentPoints().size()); - + expect(mockTopology.isAllowed(EasyMock.anyLong(), EasyMock.anyShort())).andReturn(true).anyTimes(); // Start recording the replay on the mocks replay(mockSwitch, mockTopology); @@ -328,11 +420,11 @@ public class DeviceManagerImplTest extends FloodlightTestCase { // Verify the device assertEquals(device, deviceManager.getDeviceByDataLayerAddress(dataLayerSource)); - + // Reset the device cache deviceManager.clearAllDeviceStateFromMemory(); } - + @Test public void testDeviceRecoverFromStorage() throws Exception { byte[] dataLayerSource = ((Ethernet)this.testARPReplyPacket_2).getSourceMACAddress(); @@ -340,7 +432,7 @@ public class DeviceManagerImplTest extends FloodlightTestCase { // Mock up our expected behavior IOFSwitch mockSwitch = createMock(IOFSwitch.class); ITopologyService mockTopology = createNiceMock(ITopologyService.class); - + expect(mockSwitch.getId()).andReturn(1L).anyTimes(); expect(mockSwitch.getStringId()).andReturn("00:00:00:00:00:00:00:01").anyTimes(); expect(mockTopology.isInternal(1L, (short)1)).andReturn(false); @@ -349,7 +441,7 @@ public class DeviceManagerImplTest extends FloodlightTestCase { // Start recording the replay on the mocks replay(mockSwitch, mockTopology); - + // Add the switch so the list isn't empty mockFloodlightProvider.getSwitches().put(mockSwitch.getId(), mockSwitch); @@ -364,7 +456,7 @@ public class DeviceManagerImplTest extends FloodlightTestCase { device.addAttachmentPoint(dap); device.addNetworkAddress(ipaddr, currentDate); device.addNetworkAddress(ipaddr2, currentDate); - + // Get the listener and trigger the packet ins mockFloodlightProvider.dispatchMessage(mockSwitch, this.packetIn_2); mockFloodlightProvider.dispatchMessage(mockSwitch, this.packetIn_3); @@ -374,28 +466,28 @@ public class DeviceManagerImplTest extends FloodlightTestCase { assertEquals(device, deviceManager.getDeviceByIPv4Address(ipaddr)); assertEquals(device, deviceManager.getDeviceByIPv4Address(ipaddr2)); assertEquals(dap, device.getAttachmentPoint(spt)); - + // Reset the device cache deviceManager.clearAllDeviceStateFromMemory(); - + // Verify the device assertNull(deviceManager.getDeviceByDataLayerAddress(dataLayerSource)); assertNull(deviceManager.getDeviceByIPv4Address(ipaddr)); assertNull(deviceManager.getDeviceByIPv4Address(ipaddr2)); - + // Load the device cache from storage deviceManager.readAllDeviceStateFromStorage(); - + // Verify the device Device device2 = deviceManager.getDeviceByDataLayerAddress(dataLayerSource); assertEquals(device, device2); assertEquals(dap, device2.getAttachmentPoint(spt)); - + deviceManager.clearAllDeviceStateFromMemory(); mockFloodlightProvider.setSwitches(new HashMap<Long,IOFSwitch>()); deviceManager.removedSwitch(mockSwitch); deviceManager.readAllDeviceStateFromStorage(); - + device2 = deviceManager.getDeviceByDataLayerAddress(dataLayerSource); assertEquals(device, device2); @@ -409,11 +501,11 @@ public class DeviceManagerImplTest extends FloodlightTestCase { assertEquals(device, deviceManager.getDeviceByIPv4Address(ipaddr)); assertEquals(device, deviceManager.getDeviceByIPv4Address(ipaddr2)); } - + @Test public void testDeviceUpdateLastSeenToStorage() throws Exception { deviceManager.clearAllDeviceStateFromMemory(); - + MockFloodlightProvider mockFloodlightProvider = getMockFloodlightProvider(); byte[] dataLayerSource = ((Ethernet)this.testARPReplyPacket_1).getSourceMACAddress(); @@ -439,29 +531,29 @@ public class DeviceManagerImplTest extends FloodlightTestCase { replay(mockSwitch, mockTopology); // Get the listener and trigger the packet in mockFloodlightProvider.dispatchMessage(mockSwitch, this.packetIn_1); - + Thread.sleep(100); - + // Get the listener and trigger the packet in mockFloodlightProvider.dispatchMessage(mockSwitch, this.packetIn_1); - + // Clear the device cache deviceManager.clearAllDeviceStateFromMemory(); // Load the device cache from storage deviceManager.readAllDeviceStateFromStorage(); - + // Make sure the last seen is after our date device = deviceManager.getDeviceByDataLayerAddress(dataLayerSource); assertTrue(device.getLastSeen().after(currentDate)); } - + @Test public void testAttachmentPointFlapping() throws Exception { - OFPhysicalPort port1 = new OFPhysicalPort(); - OFPhysicalPort port2 = new OFPhysicalPort(); + OFPhysicalPort port1 = new OFPhysicalPort(); + OFPhysicalPort port2 = new OFPhysicalPort(); port1.setName("port1"); port2.setName("port2"); - + byte[] dataLayerSource = ((Ethernet)this.testARPReplyPacket_1).getSourceMACAddress(); // Mock up our expected behavior @@ -475,12 +567,11 @@ public class DeviceManagerImplTest extends FloodlightTestCase { .andReturn(false).atLeastOnce(); expect(mockTopology.isInternal(1L, (short)2)) .andReturn(false).atLeastOnce(); - expect(mockTopology.getSwitchClusterId(1L)) - .andReturn(1L).atLeastOnce(); expect(mockTopology.isBroadcastDomainPort(1L, (short)1)) .andReturn(false).atLeastOnce(); expect(mockTopology.isBroadcastDomainPort(1L, (short)2)) .andReturn(false).atLeastOnce(); + expect(mockTopology.inSameCluster(1L, 1L)).andReturn(true).atLeastOnce(); deviceManager.setTopology(mockTopology); expect(mockTopology.isAllowed(EasyMock.anyLong(), EasyMock.anyShort())).andReturn(true).anyTimes(); @@ -498,7 +589,7 @@ public class DeviceManagerImplTest extends FloodlightTestCase { mockFloodlightProvider.dispatchMessage(mockSwitch, this.packetIn_1.setInPort((short)2)); Device device = deviceManager.getDeviceByDataLayerAddress(dataLayerSource); - + // Verify the replay matched our expectations verify(mockSwitch, mockTopology); @@ -508,35 +599,35 @@ public class DeviceManagerImplTest extends FloodlightTestCase { for (DeviceAttachmentPoint ap : device.getOldAttachmentPoints()) { assertTrue(ap.isBlocked()); } - + // Reset the device cache deviceManager.clearAllDeviceStateFromMemory(); } - + private static final Map<String, Object> pcPort1; static { - pcPort1 = new HashMap<String, Object>(); - pcPort1.put(DeviceManagerImpl.PORT_CHANNEL_COLUMN_NAME, "channel"); - pcPort1.put(DeviceManagerImpl.PC_PORT_COLUMN_NAME, "port1"); - pcPort1.put(DeviceManagerImpl.PC_SWITCH_COLUMN_NAME, "00:00:00:00:00:00:00:01"); - pcPort1.put(DeviceManagerImpl.PC_ID_COLUMN_NAME, "00:00:00:00:00:00:00:01|port1"); + pcPort1 = new HashMap<String, Object>(); + pcPort1.put(DeviceManagerImpl.PORT_CHANNEL_COLUMN_NAME, "channel"); + pcPort1.put(DeviceManagerImpl.PC_PORT_COLUMN_NAME, "port1"); + pcPort1.put(DeviceManagerImpl.PC_SWITCH_COLUMN_NAME, "00:00:00:00:00:00:00:01"); + pcPort1.put(DeviceManagerImpl.PC_ID_COLUMN_NAME, "00:00:00:00:00:00:00:01|port1"); } - + private static final Map<String, Object> pcPort2; static { - pcPort2 = new HashMap<String, Object>(); - pcPort2.put(DeviceManagerImpl.PORT_CHANNEL_COLUMN_NAME, "channel"); - pcPort2.put(DeviceManagerImpl.PC_PORT_COLUMN_NAME, "port2"); - pcPort2.put(DeviceManagerImpl.PC_SWITCH_COLUMN_NAME, "00:00:00:00:00:00:00:01"); - pcPort2.put(DeviceManagerImpl.PC_ID_COLUMN_NAME, "00:00:00:00:00:00:00:01|port2"); + pcPort2 = new HashMap<String, Object>(); + pcPort2.put(DeviceManagerImpl.PORT_CHANNEL_COLUMN_NAME, "channel"); + pcPort2.put(DeviceManagerImpl.PC_PORT_COLUMN_NAME, "port2"); + pcPort2.put(DeviceManagerImpl.PC_SWITCH_COLUMN_NAME, "00:00:00:00:00:00:00:01"); + pcPort2.put(DeviceManagerImpl.PC_ID_COLUMN_NAME, "00:00:00:00:00:00:00:01|port2"); } - + private void setupPortChannel() { storageSource.insertRow(DeviceManagerImpl.PORT_CHANNEL_TABLE_NAME, pcPort1); storageSource.insertRow(DeviceManagerImpl.PORT_CHANNEL_TABLE_NAME, pcPort2); deviceManager.readPortChannelConfigFromStorage(); } - + private void teardownPortChannel() { storageSource.deleteRow(DeviceManagerImpl.PORT_CHANNEL_TABLE_NAME, pcPort1.get(DeviceManagerImpl.PC_ID_COLUMN_NAME)); @@ -544,15 +635,15 @@ public class DeviceManagerImplTest extends FloodlightTestCase { pcPort2.get(DeviceManagerImpl.PC_ID_COLUMN_NAME)); deviceManager.readPortChannelConfigFromStorage(); } - + /** * The same test as testAttachmentPointFlapping except for port-channel * @throws Exception */ @Test public void testPortChannel() throws Exception { - OFPhysicalPort port1 = new OFPhysicalPort(); - OFPhysicalPort port2 = new OFPhysicalPort(); + OFPhysicalPort port1 = new OFPhysicalPort(); + OFPhysicalPort port2 = new OFPhysicalPort(); port1.setName("port1"); port2.setName("port2"); @@ -570,12 +661,11 @@ public class DeviceManagerImplTest extends FloodlightTestCase { .andReturn(false).atLeastOnce(); expect(mockTopology.isInternal(1L, (short)2)) .andReturn(false).atLeastOnce(); - expect(mockTopology.getSwitchClusterId(1L)) - .andReturn(1L).atLeastOnce(); expect(mockTopology.isBroadcastDomainPort(1L, (short)1)) .andReturn(false).atLeastOnce(); expect(mockTopology.isBroadcastDomainPort(1L, (short)2)) .andReturn(false).atLeastOnce(); + expect(mockTopology.inSameCluster(1L, 1L)).andReturn(true).atLeastOnce(); expect(mockTopology.isInSameBroadcastDomain((long)1, (short)1, (long)1, (short)2)).andReturn(false).anyTimes(); expect(mockTopology.isInSameBroadcastDomain((long)1, (short)2, @@ -595,7 +685,7 @@ public class DeviceManagerImplTest extends FloodlightTestCase { mockFloodlightProvider.dispatchMessage(mockSwitch, this.packetIn_1.setInPort((short)2)); Device device = deviceManager.getDeviceByDataLayerAddress(dataLayerSource); - + // Verify the replay matched our expectations verify(mockSwitch, mockTopology); @@ -605,10 +695,10 @@ public class DeviceManagerImplTest extends FloodlightTestCase { for (DeviceAttachmentPoint ap : device.getOldAttachmentPoints()) { assertFalse(ap.isBlocked()); } - + // Reset the device cache deviceManager.clearAllDeviceStateFromMemory(); - + teardownPortChannel(); } }