diff --git a/src/main/java/net/floodlightcontroller/core/IOFSwitch.java b/src/main/java/net/floodlightcontroller/core/IOFSwitch.java index 34c5319b5bffb127cc977049549496bbe166851e..3b46ded638f72120733d9865bc58a37c82409512 100644 --- a/src/main/java/net/floodlightcontroller/core/IOFSwitch.java +++ b/src/main/java/net/floodlightcontroller/core/IOFSwitch.java @@ -1,5 +1,4 @@ /** -* Copyright 2011, Big Switch Networks, Inc. * Originally created by David Erickson, Stanford University * * Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -214,14 +213,6 @@ public interface IOFSwitch extends IOFMessageWriter { */ DatapathId getId(); - /** - * Get a string version of the ID for this switch - * FIXME: Should get rid of this and just use getId and use the - * DatapathID serializer for getId. - * @return - */ - String getStringId(); - /** * Retrieves attributes of this switch * @return diff --git a/src/main/java/net/floodlightcontroller/core/OFSwitch.java b/src/main/java/net/floodlightcontroller/core/OFSwitch.java index d6749324f0a2539d5002560359ba6c69d5f60c8f..ee6d4c942ac235fb92c667fc7207d804630ba30c 100644 --- a/src/main/java/net/floodlightcontroller/core/OFSwitch.java +++ b/src/main/java/net/floodlightcontroller/core/OFSwitch.java @@ -884,12 +884,6 @@ public class OFSwitch implements IOFSwitchBackend { return datapathId; } - @Override - public String getStringId() { - // FIXME: Should get rid of this - return getId().toString(); - } - /* (non-Javadoc) * @see java.lang.Object#toString() */ diff --git a/src/main/java/net/floodlightcontroller/core/internal/Controller.java b/src/main/java/net/floodlightcontroller/core/internal/Controller.java index a5b2a8a0bd940aa63ce3ff74d4e081369d859ea1..db8c322d23023bf5505e6b9064cb04700daf093c 100644 --- a/src/main/java/net/floodlightcontroller/core/internal/Controller.java +++ b/src/main/java/net/floodlightcontroller/core/internal/Controller.java @@ -45,7 +45,6 @@ import net.floodlightcontroller.core.IFloodlightProviderService; import net.floodlightcontroller.core.IHAListener; import net.floodlightcontroller.core.IInfoProvider; import net.floodlightcontroller.core.IShutdownService; -import net.floodlightcontroller.core.SwitchSyncRepresentation; import net.floodlightcontroller.core.IListener.Command; import net.floodlightcontroller.core.IOFMessageListener; import net.floodlightcontroller.core.IOFSwitch; @@ -79,7 +78,6 @@ import net.floodlightcontroller.storage.IStorageSourceService; import net.floodlightcontroller.storage.StorageException; import net.floodlightcontroller.threadpool.IThreadPoolService; -import org.sdnplatform.sync.IStoreClient; import org.sdnplatform.sync.ISyncService; import org.sdnplatform.sync.ISyncService.Scope; import org.sdnplatform.sync.error.SyncException; @@ -104,7 +102,6 @@ public class Controller implements IFloodlightProviderService, IStorageSourceLis protected static final INotificationManager notifier = NotificationManagerFactory.getNotificationManager(Controller.class); static final String ERROR_DATABASE = "The controller could not communicate with the system database."; - static final String SWITCH_SYNC_STORE_NAME = Controller.class.getCanonicalName() + ".stateStore"; protected ConcurrentMap<OFType, ListenerDispatcher<OFType,IOFMessageListener>> messageListeners; @@ -134,7 +131,6 @@ public class Controller implements IFloodlightProviderService, IStorageSourceLis private IThreadPoolService threadPoolService; private ISyncService syncService; private IShutdownService shutdownService; - private IStoreClient<DatapathId, SwitchSyncRepresentation> storeClient; // Configuration options protected int openFlowPort = 6653; // new registered OF port number @@ -183,11 +179,8 @@ public class Controller implements IFloodlightProviderService, IStorageSourceLis FLOW_COLUMN_CORE_PRIORITY }; - private static final short DEFAULT_ACCESS_PRIORITY = 10; - private static final short DEFAULT_CORE_PRIORITY = 1000; - private short accessPriority = DEFAULT_ACCESS_PRIORITY; - private short corePriority = DEFAULT_CORE_PRIORITY; - + private static short DEFAULT_ACCESS_PRIORITY = 10; + private static short DEFAULT_CORE_PRIORITY = 1000; // Perf. related configuration protected static final int SEND_BUFFER_SIZE = 128 * 1024; @@ -797,13 +790,11 @@ public class Controller implements IFloodlightProviderService, IStorageSourceLis storageSourceService.createTable(CONTROLLER_TABLE_NAME, null); storageSourceService.createTable(CONTROLLER_INTERFACE_TABLE_NAME, null); storageSourceService.createTable(SWITCH_CONFIG_TABLE_NAME, null); - storageSourceService.setTablePrimaryKeyName(CONTROLLER_TABLE_NAME, - CONTROLLER_ID); + storageSourceService.setTablePrimaryKeyName(CONTROLLER_TABLE_NAME, CONTROLLER_ID); storageSourceService.addListener(CONTROLLER_INTERFACE_TABLE_NAME, this); storageSourceService.createTable(FLOW_PRIORITY_TABLE_NAME, null); - storageSourceService.setTablePrimaryKeyName(FLOW_PRIORITY_TABLE_NAME, - FLOW_COLUMN_PRIMARY_KEY); + storageSourceService.setTablePrimaryKeyName(FLOW_PRIORITY_TABLE_NAME, FLOW_COLUMN_PRIMARY_KEY); storageSourceService.addListener(FLOW_PRIORITY_TABLE_NAME, this); readFlowPriorityConfigurationFromStorage(); @@ -816,12 +807,7 @@ public class Controller implements IFloodlightProviderService, IStorageSourceLis restApiService.addRestletRoutable(new CoreWebRoutable()); try { - this.syncService.registerStore(SWITCH_SYNC_STORE_NAME, Scope.LOCAL); - this.storeClient = this.syncService.getStoreClient( - SWITCH_SYNC_STORE_NAME, - DatapathId.class, - SwitchSyncRepresentation.class); - //TODO @Ryan this.storeClient.addStoreListener(this.switchService); + this.syncService.registerStore(OFSwitchManager.SWITCH_SYNC_STORE_NAME, Scope.LOCAL); } catch (SyncException e) { throw new FloodlightModuleException("Error while setting up sync service", e); } @@ -847,10 +833,10 @@ public class Controller implements IFloodlightProviderService, IStorageSourceLis String primary_key = (String) row.get(FLOW_COLUMN_PRIMARY_KEY); if (primary_key.equals(FLOW_VALUE_PRIMARY_KEY)) { if (row.containsKey(FLOW_COLUMN_ACCESS_PRIORITY)) { - accessPriority = Short.valueOf((String) row.get(FLOW_COLUMN_ACCESS_PRIORITY)); + DEFAULT_ACCESS_PRIORITY = Short.valueOf((String) row.get(FLOW_COLUMN_ACCESS_PRIORITY)); } if (row.containsKey(FLOW_COLUMN_CORE_PRIORITY)) { - corePriority = Short.valueOf((String) row.get(FLOW_COLUMN_CORE_PRIORITY)); + DEFAULT_CORE_PRIORITY = Short.valueOf((String) row.get(FLOW_COLUMN_CORE_PRIORITY)); } } } diff --git a/src/main/java/net/floodlightcontroller/core/internal/OFSwitchManager.java b/src/main/java/net/floodlightcontroller/core/internal/OFSwitchManager.java index 09468075d51823898c3170d65957310839ae6132..b62c6241cde68226d6ef6ecb18faa281a18334eb 100644 --- a/src/main/java/net/floodlightcontroller/core/internal/OFSwitchManager.java +++ b/src/main/java/net/floodlightcontroller/core/internal/OFSwitchManager.java @@ -4,6 +4,7 @@ import java.net.InetSocketAddress; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; @@ -33,6 +34,7 @@ import net.floodlightcontroller.core.IOFSwitchListener; import net.floodlightcontroller.core.LogicalOFMessageCategory; import net.floodlightcontroller.core.PortChangeType; import net.floodlightcontroller.core.SwitchDescription; +import net.floodlightcontroller.core.SwitchSyncRepresentation; import net.floodlightcontroller.core.annotations.LogMessageDoc; import net.floodlightcontroller.core.annotations.LogMessageDocs; import net.floodlightcontroller.core.internal.Controller.IUpdate; @@ -55,6 +57,12 @@ import org.projectfloodlight.openflow.protocol.OFMessage; import org.projectfloodlight.openflow.protocol.OFPortDesc; import org.projectfloodlight.openflow.types.DatapathId; import org.projectfloodlight.openflow.types.OFAuxId; +import org.sdnplatform.sync.IStoreClient; +import org.sdnplatform.sync.IStoreListener; +import org.sdnplatform.sync.ISyncService; +import org.sdnplatform.sync.Versioned; +import org.sdnplatform.sync.error.SyncException; +import org.sdnplatform.sync.error.UnknownStoreException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -73,14 +81,21 @@ import com.google.common.collect.ImmutableSet; * @author gregor, capveg, sovietaced * */ -public class OFSwitchManager implements IOFSwitchManager, INewOFConnectionListener, IHAListener, IFloodlightModule, IOFSwitchService { +public class OFSwitchManager implements IOFSwitchManager, INewOFConnectionListener, IHAListener, IFloodlightModule, IOFSwitchService, IStoreListener<DatapathId> { private static final Logger log = LoggerFactory.getLogger(OFSwitchManager.class); private volatile OFControllerRole role; private SwitchManagerCounters counters; + private ISyncService syncService; + private IStoreClient<DatapathId, SwitchSyncRepresentation> storeClient; + public static final String SWITCH_SYNC_STORE_NAME = OFSwitchManager.class.getCanonicalName() + ".stateStore"; + + private ConcurrentHashMap<DatapathId, OFSwitchHandshakeHandler> switchHandlers; private ConcurrentHashMap<DatapathId, IOFSwitchBackend> switches; + private ConcurrentHashMap<DatapathId, IOFSwitch> syncedSwitches; + private ISwitchDriverRegistry driverRegistry; @@ -602,6 +617,7 @@ public class OFSwitchManager implements IOFSwitchManager, INewOFConnectionListen l.add(IFloodlightProviderService.class); l.add(IDebugEventService.class); l.add(IDebugCounterService.class); + l.add(ISyncService.class); return l; } @@ -612,10 +628,12 @@ public class OFSwitchManager implements IOFSwitchManager, INewOFConnectionListen floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class); debugEventService = context.getServiceImpl(IDebugEventService.class); debugCounterService = context.getServiceImpl(IDebugCounterService.class); + syncService = context.getServiceImpl(ISyncService.class); // Module variables switchHandlers = new ConcurrentHashMap<DatapathId, OFSwitchHandshakeHandler>(); switches = new ConcurrentHashMap<DatapathId, IOFSwitchBackend>(); + syncedSwitches = new ConcurrentHashMap<DatapathId, IOFSwitch>(); floodlightProvider.getTimer(); counters = new SwitchManagerCounters(debugCounterService); driverRegistry = new NaiveSwitchDriverRegistry(this); @@ -623,6 +641,16 @@ public class OFSwitchManager implements IOFSwitchManager, INewOFConnectionListen this.switchListeners = new CopyOnWriteArraySet<IOFSwitchListener>(); this.counters = new SwitchManagerCounters(debugCounterService); + /* TODO @Ryan + try { + this.storeClient = this.syncService.getStoreClient( + SWITCH_SYNC_STORE_NAME, + DatapathId.class, + SwitchSyncRepresentation.class); + this.storeClient.addStoreListener(this); + } catch (UnknownStoreException e) { + throw new FloodlightModuleException("Error while setting up sync store client", e); + } */ } @@ -741,4 +769,99 @@ public class OFSwitchManager implements IOFSwitchManager, INewOFConnectionListen Map<String, String> addedControllerNodeIPs, Map<String, String> removedControllerNodeIPs) { } + + @Override + public void keysModified(Iterator<DatapathId> keys, UpdateType type) { + if (type == UpdateType.LOCAL) { + // We only care for remote updates + return; + } + while(keys.hasNext()) { + DatapathId key = keys.next(); + Versioned<SwitchSyncRepresentation> versionedSwitch = null; + try { + versionedSwitch = storeClient.get(key); + } catch (SyncException e) { + log.error("Exception while retrieving switch " + key.toString() + + " from sync store. Skipping", e); + continue; + } + if (log.isTraceEnabled()) { + log.trace("Reveiced switch store notification: key={}, " + + "entry={}", key, versionedSwitch.getValue()); + } + // versionedSwtich won't be null. storeClient.get() always + // returns a non-null or throws an exception + if (versionedSwitch.getValue() == null) { + switchRemovedFromStore(key); + continue; + } + SwitchSyncRepresentation storedSwitch = versionedSwitch.getValue(); + IOFSwitch sw = getSwitch(storedSwitch.getDpid()); + //TODO @Ryan need to get IOFSwitchBackend setFeaturesReply(storedSwitch.getFeaturesReply(sw.getOFFactory())); + if (!key.equals(storedSwitch.getFeaturesReply(sw.getOFFactory()).getDatapathId())) { + log.error("Inconsistent DPIDs from switch sync store: " + + "key is {} but sw.getId() says {}. Ignoring", + key.toString(), sw.getId()); + continue; + } + switchAddedToStore(sw); + } + } + + /** + * Called when we receive a store notification about a switch that + * has been removed from the sync store + * @param dpid + */ + private synchronized void switchRemovedFromStore(DatapathId dpid) { + if (floodlightProvider.getRole() != HARole.STANDBY) { + return; // only read from store if slave + } + IOFSwitch oldSw = syncedSwitches.remove(dpid); + if (oldSw != null) { + addUpdateToQueue(new SwitchUpdate(dpid, SwitchUpdateType.REMOVED)); + } else { + // TODO: the switch was deleted (tombstone) before we ever + // knew about it (or was deleted repeatedly). Can this + // happen? When/how? + } + } + + /** + * Called when we receive a store notification about a new or updated + * switch. + * @param sw + */ + private synchronized void switchAddedToStore(IOFSwitch sw) { + if (floodlightProvider.getRole() != HARole.STANDBY) { + return; // only read from store if slave + } + DatapathId dpid = sw.getId(); + + IOFSwitch oldSw = syncedSwitches.put(dpid, sw); + if (oldSw == null) { + addUpdateToQueue(new SwitchUpdate(dpid, SwitchUpdateType.ADDED)); + } else { + // The switch already exists in storage, see if anything + // has changed + sendNotificationsIfSwitchDiffers(oldSw, sw); + } + } + + /** + * Check if the two switches differ in their ports or in other + * fields and if they differ enqueue a switch update + * @param oldSw + * @param newSw + */ + private synchronized void sendNotificationsIfSwitchDiffers(IOFSwitch oldSw, IOFSwitch newSw) { + /*TODO @Ryan Collection<PortChangeEvent> portDiffs = oldSw.comparePorts(newSw.getPorts()); + for (PortChangeEvent ev: portDiffs) { + SwitchUpdate update = new SwitchUpdate(newSw.getId(), + SwitchUpdateType.PORTCHANGED, + ev.port, ev.type); + addUpdateToQueue(update); + }*/ + } } diff --git a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java index 812326e5d95d07ca5150741b81eac49b230b51b4..ea3a8aba8a47268bc5bdbd7723d0747b32a369a2 100755 --- a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java +++ b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java @@ -1197,7 +1197,7 @@ public class DeviceManagerImpl implements IDeviceService, IOFMessageListener, IT if (logger.isTraceEnabled()) { logger.trace("Received PI: {} on switch {}, port {} *** eth={}" + " *** srcDev={} *** dstDev={} *** ", - new Object[] { pi, sw.getStringId(), pi.getMatch().get(MatchField.IN_PORT), eth, + new Object[] { pi, sw.getId().toString(), pi.getMatch().get(MatchField.IN_PORT), eth, srcDevice, dstDevice }); } diff --git a/src/main/java/net/floodlightcontroller/firewall/FirewallRule.java b/src/main/java/net/floodlightcontroller/firewall/FirewallRule.java index fb99e5612ba921f3dcff4628eea88d142e777e54..b32d9c10ace35606a59447094f74585d58443f41 100644 --- a/src/main/java/net/floodlightcontroller/firewall/FirewallRule.java +++ b/src/main/java/net/floodlightcontroller/firewall/FirewallRule.java @@ -215,7 +215,7 @@ public class FirewallRule implements Comparable<FirewallRule> { } // mac address (src and dst) match? - if (any_dl_src == false && !dl_src.equals(packet.getSourceMAC())) + if (any_dl_src == false && !dl_src.equals(packet.getSourceMACAddress())) return false; if (action == FirewallRule.FirewallAction.DROP) { //wildcards.drop &= ~OFMatch.OFPFW_DL_SRC; @@ -225,7 +225,7 @@ public class FirewallRule implements Comparable<FirewallRule> { adp.allow.setExact(MatchField.ETH_SRC, this.dl_src); } - if (any_dl_dst == false && !dl_dst.equals(packet.getDestinationMAC())) + if (any_dl_dst == false && !dl_dst.equals(packet.getDestinationMACAddress())) return false; if (action == FirewallRule.FirewallAction.DROP) { //wildcards.drop &= ~OFMatch.OFPFW_DL_DST; diff --git a/src/main/java/net/floodlightcontroller/forwarding/Forwarding.java b/src/main/java/net/floodlightcontroller/forwarding/Forwarding.java index 3732d38e379d2ffc05ee35b6e212ceb28e5843c3..77ebe9a8a66c831e95248610c6c63979fe4c8541 100644 --- a/src/main/java/net/floodlightcontroller/forwarding/Forwarding.java +++ b/src/main/java/net/floodlightcontroller/forwarding/Forwarding.java @@ -186,7 +186,7 @@ public class Forwarding extends ForwardingBase implements IFloodlightModule { } if (srcIsland == null) { log.debug("No openflow island found for source {}/{}", - sw.getStringId(), pi.getMatch().get(MatchField.IN_PORT)); + sw.getId().toString(), pi.getMatch().get(MatchField.IN_PORT)); return; } @@ -282,8 +282,11 @@ public class Forwarding extends ForwardingBase implements IFloodlightModule { // With a normal builder, all parent MatchFields will be lost if any MatchFields are added, mod, del Match.Builder mb = MatchUtils.createRetentiveBuilder(m); mb.setExact(MatchField.ETH_SRC, srcMac) - .setExact(MatchField.ETH_DST, dstMac) - .setExact(MatchField.VLAN_VID, OFVlanVidMatch.ofVlanVid(vlan)); + .setExact(MatchField.ETH_DST, dstMac); + + if (!vlan.equals(VlanVid.ZERO)) { + mb.setExact(MatchField.VLAN_VID, OFVlanVidMatch.ofVlanVid(vlan)); + } if (eth.getEtherType() == Ethernet.TYPE_IPv4) { IPv4 ip = (IPv4) eth.getPayload(); diff --git a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java b/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java index f14435cb6e83a56b923808785f41767a5c4fddd3..f280411b48d95509c79256915e76fec8f7a20674 100644 --- a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java +++ b/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java @@ -697,7 +697,7 @@ IFloodlightModule, IInfoProvider { if (!remoteSwitch.portEnabled(remotePort)) { if (log.isTraceEnabled()) { log.trace("Ignoring link with disabled source port: switch {} port {} {}", - new Object[] { remoteSwitch.getStringId(), + new Object[] { remoteSwitch.getId().toString(), remotePort, remoteSwitch.getPort(remotePort)}); } @@ -708,7 +708,7 @@ IFloodlightModule, IInfoProvider { remotePort))) { if (log.isTraceEnabled()) { log.trace("Ignoring link with suppressed src port: switch {} port {} {}", - new Object[] { remoteSwitch.getStringId(), + new Object[] { remoteSwitch.getId().toString(), remotePort, remoteSwitch.getPort(remotePort)}); } diff --git a/src/main/java/net/floodlightcontroller/loadbalancer/LoadBalancer.java b/src/main/java/net/floodlightcontroller/loadbalancer/LoadBalancer.java index e81c4d9b4229e362f8195d707c0bc66d2eec7258..b70a646f90896caf75169b19fa3d358e2155f061 100644 --- a/src/main/java/net/floodlightcontroller/loadbalancer/LoadBalancer.java +++ b/src/main/java/net/floodlightcontroller/loadbalancer/LoadBalancer.java @@ -409,7 +409,7 @@ public class LoadBalancer implements IFloodlightModule, if (srcIsland == null) { log.debug("No openflow island found for source {}/{}", - sw.getStringId(), pi.getInPort()); + sw.getId().toString(), pi.getInPort()); return; } diff --git a/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java b/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java index 3374d27eda938404a9a48cec3206bff037f412be..48e7dfd8ab8d4a36dac83c2503630711c48d6664 100644 --- a/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java +++ b/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java @@ -189,7 +189,7 @@ implements IOFSwitchListener, IFloodlightModule, IStaticFlowEntryPusherService, IOFSwitch sw = switchService.getSwitch(switchId); if (sw == null) return; - String stringId = sw.getStringId(); + String stringId = sw.getId().toString(); if ((entriesFromStorage != null) && (entriesFromStorage.containsKey(stringId))) { Map<String, OFFlowMod> entries = entriesFromStorage.get(stringId);