/** * Given a new or modified port newPort, returns the list of PortChangeEvents to "transform" the * current ports stored by this switch to include / represent the new port. The ports stored by * this switch are <b>NOT</b> updated. * * <p>This method acquires the readlock and is thread-safe by itself. Most callers will need to * acquire the write lock before calling this method though (if the caller wants to update the * ports stored by this switch) * * @param newPort the new or modified port. * @return the list of changes */ public OrderedCollection<PortChangeEvent> getSinglePortChanges(OFPortDesc newPort) { lock.readLock().lock(); try { OrderedCollection<PortChangeEvent> events = new LinkedHashSetWrapper<PortChangeEvent>(); // Check if we have a port by the same number in our // old map. OFPortDesc prevPort = portsByNumber.get(newPort.getPortNo()); if (newPort.equals(prevPort)) { // nothing has changed return events; } if (prevPort != null && prevPort.getName().equals(newPort.getName())) { // A simple modify of a exiting port // A previous port with this number exists and it's name // also matches the new port. Find the differences if ((!prevPort.getState().contains(OFPortState.LINK_DOWN) && !prevPort.getConfig().contains(OFPortConfig.PORT_DOWN)) && (newPort.getState().contains(OFPortState.LINK_DOWN) || newPort.getConfig().contains(OFPortConfig.PORT_DOWN))) { events.add(new PortChangeEvent(newPort, PortChangeType.DOWN)); } else if ((prevPort.getState().contains(OFPortState.LINK_DOWN) || prevPort.getConfig().contains(OFPortConfig.PORT_DOWN)) && (!newPort.getState().contains(OFPortState.LINK_DOWN) && !newPort.getConfig().contains(OFPortConfig.PORT_DOWN))) { events.add(new PortChangeEvent(newPort, PortChangeType.UP)); } else { events.add(new PortChangeEvent(newPort, PortChangeType.OTHER_UPDATE)); } return events; } if (prevPort != null) { // There exists a previous port with the same port // number but the port name is different (otherwise we would // never have gotten here) // Remove the port. Name-number mapping(s) have changed events.add(new PortChangeEvent(prevPort, PortChangeType.DELETE)); } // We now need to check if there exists a previous port sharing // the same name as the new/updated port. prevPort = portsByName.get(newPort.getName().toLowerCase()); if (prevPort != null) { // There exists a previous port with the same port // name but the port number is different (otherwise we // never have gotten here). // Remove the port. Name-number mapping(s) have changed events.add(new PortChangeEvent(prevPort, PortChangeType.DELETE)); } // We always need to add the new port. Either no previous port // existed or we just deleted previous ports with inconsistent // name-number mappings events.add(new PortChangeEvent(newPort, PortChangeType.ADD)); return events; } finally { lock.readLock().unlock(); } }