diff --git a/src/main/java/net/floodlightcontroller/core/OFMessageFilterManager.java b/src/main/java/net/floodlightcontroller/core/OFMessageFilterManager.java index 5d9a38fc947bae9a079a64f11df579bbe2b652c0..777bfaf44d87997e9a4020f7beec87977e698620 100644 --- a/src/main/java/net/floodlightcontroller/core/OFMessageFilterManager.java +++ b/src/main/java/net/floodlightcontroller/core/OFMessageFilterManager.java @@ -423,11 +423,11 @@ public class OFMessageFilterManager packetClient.pushMessageAsync(sendMsg); } } catch (TTransportException e) { - log.error("Caught TTransportException: {}", e); + log.error("Caught TTransportException: {}", e.getMessage()); disconnectFromPSServer(); connectToPSServer(); } catch (Exception e) { - log.error("Caught exception: {}", e); + log.error("Caught exception: {}", e.getMessage()); disconnectFromPSServer(); connectToPSServer(); } diff --git a/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImpl.java b/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImpl.java index 7f06870ca1085fabf50e2eebf3a9beeabd8de5d2..948714f079d8a3806e0bf0377282e58d1bfe1a99 100644 --- a/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImpl.java +++ b/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImpl.java @@ -18,8 +18,10 @@ package net.floodlightcontroller.core.internal; import java.io.IOException; +import java.net.SocketAddress; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.LinkedList; @@ -37,11 +39,14 @@ import net.floodlightcontroller.core.IFloodlightProviderService; import net.floodlightcontroller.core.IOFMessageListener; import net.floodlightcontroller.core.IFloodlightProviderService.Role; import net.floodlightcontroller.core.IOFSwitch; -import net.floodlightcontroller.core.types.MacVlanPair; +import net.floodlightcontroller.core.web.serializers.DPIDSerializer; import net.floodlightcontroller.threadpool.IThreadPoolService; import net.floodlightcontroller.util.TimedCache; import org.codehaus.jackson.annotate.JsonIgnore; +import org.codehaus.jackson.annotate.JsonProperty; +import org.codehaus.jackson.map.annotate.JsonSerialize; +import org.codehaus.jackson.map.ser.ToStringSerializer; import org.jboss.netty.channel.Channel; import org.openflow.protocol.OFFeaturesReply; import org.openflow.protocol.OFFlowMod; @@ -82,8 +87,6 @@ public class OFSwitchImpl implements IOFSwitch { protected Channel channel; protected AtomicInteger transactionIdSource; protected Map<Short, OFPhysicalPort> ports; - protected Long switchClusterId; - protected Map<MacVlanPair,Short> macVlanToPortMap; protected Map<Integer,OFStatisticsFuture> statsFutureMap; protected Map<Integer, IOFMessageListener> iofMsgListenersMap; protected boolean connected; @@ -132,7 +135,6 @@ public class OFSwitchImpl implements IOFSwitch { this.connectedSince = new Date(); this.transactionIdSource = new AtomicInteger(); this.ports = new ConcurrentHashMap<Short, OFPhysicalPort>(); - this.switchClusterId = null; this.connected = true; this.statsFutureMap = new ConcurrentHashMap<Integer,OFStatisticsFuture>(); this.iofMsgListenersMap = new ConcurrentHashMap<Integer,IOFMessageListener>(); @@ -241,27 +243,20 @@ public class OFSwitchImpl implements IOFSwitch { channel.close(); } + @JsonIgnore public OFFeaturesReply getFeaturesReply() { return this.featuresReply; } - public void setSwitchClusterId(Long id) { - this.switchClusterId = id; - } - - public Long getSwitchClusterId() { - return switchClusterId; - } - public synchronized void setFeaturesReply(OFFeaturesReply featuresReply) { this.featuresReply = featuresReply; for (OFPhysicalPort port : featuresReply.getPorts()) { ports.put(port.getPortNumber(), port); } - this.switchClusterId = featuresReply.getDatapathId(); this.stringId = HexString.toHexString(featuresReply.getDatapathId()); } + @JsonIgnore public synchronized List<OFPhysicalPort> getEnabledPorts() { List<OFPhysicalPort> result = new ArrayList<OFPhysicalPort>(); for (OFPhysicalPort port : ports.values()) { @@ -280,9 +275,15 @@ public class OFSwitchImpl implements IOFSwitch { ports.put(port.getPortNumber(), port); } + @JsonIgnore public Map<Short, OFPhysicalPort> getPorts() { return ports; } + + @JsonProperty("ports") + public Collection<OFPhysicalPort> getPortCollection() { + return ports.values(); + } public synchronized void deletePort(short portNumber) { ports.remove(portNumber); @@ -306,12 +307,15 @@ public class OFSwitchImpl implements IOFSwitch { } @Override + @JsonSerialize(using=DPIDSerializer.class) + @JsonProperty("dpid") public long getId() { if (this.featuresReply == null) throw new RuntimeException("Features reply has not yet been set"); return this.featuresReply.getDatapathId(); } + @JsonIgnore @Override public String getStringId() { return stringId; @@ -335,6 +339,7 @@ public class OFSwitchImpl implements IOFSwitch { return connectedSince; } + @JsonIgnore @Override public int getNextTransactionId() { return this.transactionIdSource.incrementAndGet(); @@ -409,6 +414,7 @@ public class OFSwitchImpl implements IOFSwitch { this.threadPool = tp; } + @JsonIgnore @Override public synchronized boolean isConnected() { return connected; @@ -424,6 +430,7 @@ public class OFSwitchImpl implements IOFSwitch { return role; } + @JsonIgnore @Override public boolean isActive() { return (role != Role.SLAVE); @@ -469,6 +476,7 @@ public class OFSwitchImpl implements IOFSwitch { } @Override + @JsonIgnore public Map<Short, Long> getPortBroadcastHits() { return this.portBroadcastCacheHitMap; } @@ -517,6 +525,15 @@ public class OFSwitchImpl implements IOFSwitch { public Lock getListenerWriteLock() { return listenerLock.writeLock(); } + + /** + * Get the IP Address for the switch + * @return the inet address + */ + @JsonSerialize(using=ToStringSerializer.class) + public SocketAddress getInetAddress() { + return channel.getRemoteAddress(); + } /** * Send NX role request message to the switch requesting the specified role. diff --git a/src/main/java/net/floodlightcontroller/core/web/ControllerSwitchesResource.java b/src/main/java/net/floodlightcontroller/core/web/ControllerSwitchesResource.java index c8f74860e7369ecb789be974bc3343ba86afcf78..726a7d18f640d8416b5ec4915a3a79ff6c853396 100644 --- a/src/main/java/net/floodlightcontroller/core/web/ControllerSwitchesResource.java +++ b/src/main/java/net/floodlightcontroller/core/web/ControllerSwitchesResource.java @@ -17,10 +17,7 @@ package net.floodlightcontroller.core.web; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.Collection; import net.floodlightcontroller.core.IFloodlightProviderService; import net.floodlightcontroller.core.IOFSwitch; @@ -34,18 +31,10 @@ import org.restlet.resource.ServerResource; */ public class ControllerSwitchesResource extends ServerResource { @Get("json") - public List<Map<String, String>> retrieve() { - List<Map<String, String>> switchIds = new ArrayList<Map<String, String>>(); + public Collection<IOFSwitch> retrieve() { IFloodlightProviderService floodlightProvider = (IFloodlightProviderService)getContext().getAttributes(). get(IFloodlightProviderService.class.getCanonicalName()); - Map<Long, IOFSwitch> switches = floodlightProvider.getSwitches(); - - for (IOFSwitch s: switches.values()) { - Map<String, String> m = new HashMap<String, String>(); - m.put("dpid", s.getStringId()); - switchIds.add(m); - } - return switchIds; + return floodlightProvider.getSwitches().values(); } } diff --git a/src/main/java/net/floodlightcontroller/core/web/serializers/ByteArrayMACSerializer.java b/src/main/java/net/floodlightcontroller/core/web/serializers/ByteArrayMACSerializer.java new file mode 100644 index 0000000000000000000000000000000000000000..66c33f55bfbf5262049c9cf60c2c730fcd69a04a --- /dev/null +++ b/src/main/java/net/floodlightcontroller/core/web/serializers/ByteArrayMACSerializer.java @@ -0,0 +1,40 @@ +/** +* Copyright 2011,2012 Big Switch Networks, Inc. +* Originally created by David Erickson, Stanford University +* +* Licensed under the Apache License, Version 2.0 (the "License"); you may +* not use this file except in compliance with the License. You may obtain +* a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +* License for the specific language governing permissions and limitations +* under the License. +**/ + +package net.floodlightcontroller.core.web.serializers; + +import java.io.IOException; + +import org.codehaus.jackson.JsonGenerator; +import org.codehaus.jackson.JsonProcessingException; +import org.codehaus.jackson.map.JsonSerializer; +import org.codehaus.jackson.map.SerializerProvider; +import org.openflow.util.HexString; + +/** + * Serialize a MAC as colon-separated hexadecimal + */ +public class ByteArrayMACSerializer extends JsonSerializer<byte[]> { + + @Override + public void serialize(byte[] mac, JsonGenerator jGen, + SerializerProvider serializer) + throws IOException, JsonProcessingException { + jGen.writeString(HexString.toHexString(mac)); + } + +} diff --git a/src/main/java/net/floodlightcontroller/core/web/serializers/UShortSerializer.java b/src/main/java/net/floodlightcontroller/core/web/serializers/UShortSerializer.java new file mode 100644 index 0000000000000000000000000000000000000000..c125c76fc6138924f4ac04ceb918ca7dcbe80d90 --- /dev/null +++ b/src/main/java/net/floodlightcontroller/core/web/serializers/UShortSerializer.java @@ -0,0 +1,40 @@ +/** +* Copyright 2011,2012 Big Switch Networks, Inc. +* Originally created by David Erickson, Stanford University +* +* Licensed under the Apache License, Version 2.0 (the "License"); you may +* not use this file except in compliance with the License. You may obtain +* a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +* License for the specific language governing permissions and limitations +* under the License. +**/ + +package net.floodlightcontroller.core.web.serializers; + +import java.io.IOException; + +import org.codehaus.jackson.JsonGenerator; +import org.codehaus.jackson.JsonProcessingException; +import org.codehaus.jackson.map.JsonSerializer; +import org.codehaus.jackson.map.SerializerProvider; + +/** + * Serialize a short value as an unsigned short + */ +public class UShortSerializer extends JsonSerializer<Short> { + + @Override + public void serialize(Short s, JsonGenerator jGen, + SerializerProvider serializer) throws IOException, + JsonProcessingException { + if (s == null) jGen.writeNull(); + else jGen.writeNumber(s.shortValue() & 0xffff); + } + +} diff --git a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java index 075e18c996e40ebbba659e1e522df58d06608759..4015dea4d8e9d53881fd1c099cca3756c5ec8a77 100755 --- a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java +++ b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java @@ -853,11 +853,18 @@ IFlowReconcileListener, IInfoProvider, IHAListener { if ((dlAddrArr[0] & 0x1) != 0) return null; - long swDpid = ofmWithSwDpid.getSwitchDataPathId(); - short inPort = ofmWithSwDpid.getOfMatch().getInputPort(); + Long swDpid = null; + Short inPort = null; + + if (isSource) { + swDpid = ofmWithSwDpid.getSwitchDataPathId(); + inPort = ofmWithSwDpid.getOfMatch().getInputPort(); + } boolean learnap = true; - if (!isValidAttachmentPoint(swDpid, inPort)) { + if (swDpid == null || + inPort == null || + !isValidAttachmentPoint(swDpid, inPort)) { // If this is an internal port or we otherwise don't want // to learn on these ports. In the future, we should // handle this case by labeling flows with something that diff --git a/src/main/java/net/floodlightcontroller/flowcache/FCQueryObj.java b/src/main/java/net/floodlightcontroller/flowcache/FCQueryObj.java index 058820b4065b2ed0ffcf4230d0cdad6f6db235dd..f78aaaeed818ed6b24b5dcceb8152315f4454e2e 100644 --- a/src/main/java/net/floodlightcontroller/flowcache/FCQueryObj.java +++ b/src/main/java/net/floodlightcontroller/flowcache/FCQueryObj.java @@ -4,7 +4,6 @@ import java.util.Arrays; import net.floodlightcontroller.devicemanager.IDevice; import net.floodlightcontroller.flowcache.IFlowCacheService.FCQueryEvType; -import net.floodlightcontroller.flowcache.IFlowCacheService.FCQueryType; /** @@ -14,8 +13,6 @@ public class FCQueryObj { /** The caller of the flow cache query. */ public IFlowQueryHandler fcQueryHandler; - /** The query type. */ - public FCQueryType queryType; /** The application instance name. */ public String applInstName; /** The vlan Id. */ @@ -36,14 +33,37 @@ public class FCQueryObj { /** * Instantiates a new flow cache query object */ - public FCQueryObj() { - queryType = FCQueryType.UNKNOWN; + public FCQueryObj(IFlowQueryHandler fcQueryHandler, + String applInstName, + Short vlan, + IDevice srcDevice, + IDevice dstDevice, + String callerName, + FCQueryEvType evType, + Object callerOpaqueObj) { + this.fcQueryHandler = fcQueryHandler; + this.applInstName = applInstName; + this.srcDevice = srcDevice; + this.dstDevice = dstDevice; + this.callerName = callerName; + this.evType = evType; + this.callerOpaqueObj = callerOpaqueObj; + + if (vlan != null) { + this.vlans = new Short[] { vlan }; + } else { + if (srcDevice != null) { + this.vlans = srcDevice.getVlanId(); + } else if (dstDevice != null) { + this.vlans = dstDevice.getVlanId(); + } + } } @Override public String toString() { return "FCQueryObj [fcQueryCaller=" + fcQueryHandler - + ", queryType=" + queryType + ", applInstName=" + + ", applInstName=" + applInstName + ", vlans=" + Arrays.toString(vlans) + ", dstDevice=" + dstDevice + ", srcDevice=" + srcDevice + ", callerName=" + callerName + ", evType=" diff --git a/src/main/java/net/floodlightcontroller/flowcache/FlowCacheQueryResp.java b/src/main/java/net/floodlightcontroller/flowcache/FlowCacheQueryResp.java index cb15ee6bb2d131d1a9cdca29cacfc669b8c7288e..b01aedfe9b09433268bcad10eeff66510a6e658f 100644 --- a/src/main/java/net/floodlightcontroller/flowcache/FlowCacheQueryResp.java +++ b/src/main/java/net/floodlightcontroller/flowcache/FlowCacheQueryResp.java @@ -16,6 +16,12 @@ public class FlowCacheQueryResp { * query. */ public boolean moreFlag; + + /** + * Set to true if the response has been sent to handler + */ + public boolean hasSent; + /** * The flow list. If there are large number of flows to be returned * then they may be returned in multiple callbacks. @@ -32,6 +38,7 @@ public class FlowCacheQueryResp { qrFlowCacheObjList = new ArrayList<QRFlowCacheObj>(); queryObj = query; moreFlag = false; + hasSent = false; } /* (non-Javadoc) @@ -39,12 +46,8 @@ public class FlowCacheQueryResp { */ @Override public String toString() { - String s = queryObj.toString(); - if (moreFlag) { - s += "; moreFlasg=True"; - } else { - s += "; moreFlag=False"; - } + String s = queryObj.toString() + "; moreFlasg=" + moreFlag + + "; hasSent=" + hasSent; s += "; FlowCount=" + Integer.toString(qrFlowCacheObjList.size()); return s; } diff --git a/src/main/java/net/floodlightcontroller/flowcache/FlowReconcileManager.java b/src/main/java/net/floodlightcontroller/flowcache/FlowReconcileManager.java index f977dbc3ec75667974c1ac58d5d448762b430890..e48f3adcc306fd89d111af90da8f6ff9352c1b84 100644 --- a/src/main/java/net/floodlightcontroller/flowcache/FlowReconcileManager.java +++ b/src/main/java/net/floodlightcontroller/flowcache/FlowReconcileManager.java @@ -33,10 +33,6 @@ public class FlowReconcileManager * need to be reconciled with the current configuration of the controller. */ protected ListenerDispatcher<OFType, IFlowReconcileListener> flowReconcileListeners; - - public OFMatchReconcile newOFMatchReconcile() { - return new OFMatchReconcile(); - } @Override public synchronized void addFlowReconcileListener(IFlowReconcileListener listener) { @@ -89,19 +85,23 @@ public class FlowReconcileManager } @Override - public void updateFlowForDestinationDevice(IDevice device, FCQueryEvType fcEvType){ + public void updateFlowForDestinationDevice(IDevice device, + IFlowQueryHandler handler, + FCQueryEvType fcEvType) { // NO-OP } @Override - public void updateFlowForSourceDevice(IDevice device, FCQueryEvType fcEvType){ + public void updateFlowForSourceDevice(IDevice device, + IFlowQueryHandler handler, + FCQueryEvType fcEvType) { // NO-OP } @Override public void flowQueryGenericHandler(FlowCacheQueryResp flowResp) { if (flowResp.queryObj.evType != FCQueryEvType.GET) { - OFMatchReconcile ofmRc = newOFMatchReconcile(); + OFMatchReconcile ofmRc = new OFMatchReconcile();; /* Re-provision these flows */ for (QRFlowCacheObj entry : flowResp.qrFlowCacheObjList) { /* reconcile the flows in entry */ diff --git a/src/main/java/net/floodlightcontroller/flowcache/IFlowCacheService.java b/src/main/java/net/floodlightcontroller/flowcache/IFlowCacheService.java index ad489041224162e59cb29104ac30ab20195ac4b2..8e44ed3303d054e78b6e40107f7ea0fbeb1ac2a5 100644 --- a/src/main/java/net/floodlightcontroller/flowcache/IFlowCacheService.java +++ b/src/main/java/net/floodlightcontroller/flowcache/IFlowCacheService.java @@ -6,7 +6,6 @@ import net.floodlightcontroller.core.FloodlightContext; import net.floodlightcontroller.core.FloodlightContextStore; import net.floodlightcontroller.core.IOFSwitch; import net.floodlightcontroller.devicemanager.SwitchPort; -import net.floodlightcontroller.devicemanager.IDevice; import net.floodlightcontroller.core.module.IFloodlightService; /** @@ -26,18 +25,6 @@ public interface IFlowCacheService extends IFloodlightService { "net.floodlightcontroller.flowcache.appName"; public static final String FLOWCACHE_APP_INSTANCE_NAME = "net.floodlightcontroller.flowcache.appInstanceName"; - - /** - * The Enum FCQueryType. - */ - public enum FCQueryType { - APPLINSTNAME, // The APPLINSTNAME. - APPLINSTNAME_VLAN, // The APPLINSTNAM e_ vlan. - ALLAPP_DESTDEVICE, // The destdevice for all application. - ALLAPP_SRCDEVICE, // The source device for all application. - ALLAPP_SRCDEVICE_DESTDEVICE, // The APPLINSTNAM srcdevic destdevice. - UNKNOWN, // The UNKNOWN. - } /** * The flow cache query event type indicating the event that triggered the @@ -97,71 +84,6 @@ public interface IFlowCacheService extends IFloodlightService { */ public void submitFlowCacheQuery(FCQueryObj query); - /** - * Get a new flow cache query object populated with the supplied parameters. - * The query type field id populated automatically based on the parameters - * passed. - * - * @param fcQueryCaller the caller of this API - * @param applInstName the application instance name - * @param callerOpaqueData opaque data passed by the caller which is - * returned unchanged in the corresponding callback. - * @return a new initialized flow cache query object - */ - public FCQueryObj newFCQueryObj(IFlowQueryHandler fcQueryHandler, - String applInstName, - String callerName, - FCQueryEvType evType, - Object callerOpaqueObj); - - /** - * Get a new flow cache query object populated with the supplied parameters. - * The query type field id populated automatically based on the parameters - * passed. - * - * @param fcQueryCaller the caller of this API - * @param applInstName the application instance name - * @param vlan VLAN ID - * @param callerOpaqueData opaque data passed by the caller which is - * returned unchanged in the corresponding callback. - * @return a new initialized flow cache query object - */ - public FCQueryObj newFCQueryObj(IFlowQueryHandler fcQueryHandler, - String applInstName, - short vlan, - String callerName, - FCQueryEvType evType, - Object callerOpaqueObj); - - /** - * Get a new flow cache query object populated with the supplied parameters. - * The query type field id populated automatically based on the parameters - * passed. - * - * @param fcQueryCaller the caller of this API - * @param applInstName the application instance name - * @param srcDevice source device object - * @param dstDevice destination device object - * @param callerOpaqueData opaque data passed by the caller which is - * returned unchanged in the corresponding callback. - * @return a new initialized flow cache query object - */ - public FCQueryObj newFCQueryObj(IFlowQueryHandler fcQueryHandler, - IDevice srcDevice, - IDevice dstDevice, - String callerName, - FCQueryEvType evType, - Object callerOpaqueObj); - - /** - * Get a new flow cache query object populated with the supplied parameters. - * The query type field id populated automatically based on the parameters - * passed. - * - * @return a new uninitialized flow cache query object - */ - public FCQueryObj newFCQueryObj(); - /** * Deactivates all flows in the flow cache for which the source switch * matches the given switchDpid. Note that the flows are NOT deleted @@ -245,18 +167,6 @@ public interface IFlowCacheService extends IFloodlightService { */ public boolean moveFlowToDifferentApplInstName(OFMatchReconcile ofMRc); - /** - * Move all the flows from their current application instance to a - * different application instance. This API can be used when all flows in - * an application instance move to a different application instance when - * the application instance configuration changes. - * - * @param curApplInstName current application instance name - * @param newApplInstName new application instance name - */ - public void moveFlowToDifferentApplInstName(String curApplInstName, - String newApplInstName); - /** * Delete all flow from the specified switch * @param sw diff --git a/src/main/java/net/floodlightcontroller/flowcache/IFlowReconcileService.java b/src/main/java/net/floodlightcontroller/flowcache/IFlowReconcileService.java index 387c7d57c36cf488b48d36549b4077f0572f347c..f48c4e085c4bebc964bf2cfac3bb25c191714d2f 100644 --- a/src/main/java/net/floodlightcontroller/flowcache/IFlowReconcileService.java +++ b/src/main/java/net/floodlightcontroller/flowcache/IFlowReconcileService.java @@ -43,10 +43,13 @@ public interface IFlowReconcileService extends IFloodlightService { * new attachment point * * @param device device that has moved + * @param handler handler to process the flows * @param fcEvType Event type that triggered the update * */ - public void updateFlowForDestinationDevice(IDevice device, FCQueryEvType fcEvType); + public void updateFlowForDestinationDevice(IDevice device, + IFlowQueryHandler handler, + FCQueryEvType fcEvType); /** * Updates the flows from a device @@ -56,10 +59,13 @@ public interface IFlowReconcileService extends IFloodlightService { * new attachment point * * @param device device where the flow originates + * @param handler handler to process the flows * @param fcEvType Event type that triggered the update * */ - public void updateFlowForSourceDevice(IDevice device, FCQueryEvType fcEvType); + public void updateFlowForSourceDevice(IDevice device, + IFlowQueryHandler handler, + FCQueryEvType fcEvType); /** * Generic flow query handler to insert FlowMods into the reconcile pipeline. diff --git a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java b/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java index e143848a1fa7c48d8456a9d7fb104da7ba241c10..2d2c83115f61a4bb01b39b3f59565d674f578d0d 100644 --- a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java +++ b/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java @@ -1550,6 +1550,7 @@ public class LinkDiscoveryManager switch(newRole) { case MASTER: if (oldRole == Role.SLAVE) { + clearAllLinks(); log.debug("Sending LLDPs " + "to HA change from SLAVE->MASTER"); sendLLDPs(); diff --git a/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java b/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java index a2eae4a43096dbbb083b3dab5be604ef058b8ced..445956a4d01cc8dd0bd40b1276f5275859f0c01d 100644 --- a/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java +++ b/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java @@ -47,11 +47,9 @@ import org.openflow.protocol.OFMatch; import org.openflow.protocol.OFMessage; import org.openflow.protocol.OFPacketIn; import org.openflow.protocol.OFPacketOut; -import org.openflow.protocol.OFPort; import org.openflow.protocol.OFType; import org.openflow.protocol.action.OFAction; import org.openflow.protocol.action.OFActionOutput; -import org.openflow.util.U16; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -534,29 +532,6 @@ public abstract class ForwardingBase implements @Override public void deviceMoved(IDevice device) { - // Build flow mod to delete based on destination mac == device mac - OFMatch match = new OFMatch(); - match.setDataLayerDestination(Ethernet.toByteArray(device.getMACAddress())); - match.setWildcards(OFMatch.OFPFW_ALL ^ OFMatch.OFPFW_DL_DST); - long cookie = - AppCookie.makeCookie(FORWARDING_APP_ID, 0); - OFMessage fm = ((OFFlowMod) floodlightProvider.getOFMessageFactory() - .getMessage(OFType.FLOW_MOD)) - .setCommand(OFFlowMod.OFPFC_DELETE) - .setOutPort((short) OFPort.OFPP_NONE.getValue()) - .setMatch(match) - .setCookie(cookie) - .setLength(U16.t(OFFlowMod.MINIMUM_LENGTH)); - - // Flush to all switches - for (IOFSwitch outSw : floodlightProvider.getSwitches().values()) { - try { - outSw.write(fm, null); - } catch (IOException e) { - log.error("Failure sending flow mod delete for moved device", - e); - } - } } @Override diff --git a/src/main/java/org/openflow/protocol/OFPhysicalPort.java b/src/main/java/org/openflow/protocol/OFPhysicalPort.java index 009bef529214bb6c82826af778fe860f4835f364..58fdae59f56de9df28358e65f1b9cab038ab676e 100644 --- a/src/main/java/org/openflow/protocol/OFPhysicalPort.java +++ b/src/main/java/org/openflow/protocol/OFPhysicalPort.java @@ -21,16 +21,16 @@ import java.io.UnsupportedEncodingException; import java.nio.charset.Charset; import java.util.Arrays; +import net.floodlightcontroller.core.web.serializers.ByteArrayMACSerializer; +import net.floodlightcontroller.core.web.serializers.UShortSerializer; import org.codehaus.jackson.map.annotate.JsonSerialize; import org.jboss.netty.buffer.ChannelBuffer; -import org.openflow.protocol.serializers.OFPhysicalPortJSONSerializer; /** * Represents ofp_phy_port * @author David Erickson (daviderickson@cs.stanford.edu) - Mar 25, 2010 */ -@JsonSerialize(using=OFPhysicalPortJSONSerializer.class) public class OFPhysicalPort { public static int MINIMUM_LENGTH = 48; public static int OFP_ETH_ALEN = 6; @@ -221,6 +221,7 @@ public class OFPhysicalPort { /** * @return the portNumber */ + @JsonSerialize(using=UShortSerializer.class) public short getPortNumber() { return portNumber; } @@ -235,6 +236,7 @@ public class OFPhysicalPort { /** * @return the hardwareAddress */ + @JsonSerialize(using=ByteArrayMACSerializer.class) public byte[] getHardwareAddress() { return hardwareAddress; } diff --git a/src/main/java/org/openflow/protocol/factory/BasicFactory.java b/src/main/java/org/openflow/protocol/factory/BasicFactory.java index 553664dd526cfa0415f29bf4943b6a7bb77d823f..e0296e3f52fc59b9c898d12cbfe9597bc4e02e00 100644 --- a/src/main/java/org/openflow/protocol/factory/BasicFactory.java +++ b/src/main/java/org/openflow/protocol/factory/BasicFactory.java @@ -113,7 +113,19 @@ public class BasicFactory implements OFMessageFactory, OFActionFactory, return ofm; } catch (Exception e) { - throw new MessageParseException(e); + /* Write the offending data along with the error message */ + data.resetReaderIndex(); + int len = data.readableBytes(); + StringBuffer sb = new StringBuffer(); + for (int i=0 ; i<len; i++) { + sb.append(String.format(" %02x", data.getUnsignedByte(i))); + if (i%16 == 15) sb.append("\n"); + } + String msg = + "Message Parse Error for packet: " + sb.toString() + + "\nException: " + e.toString(); + + throw new MessageParseException(msg, e); } } diff --git a/src/main/java/org/openflow/protocol/factory/MessageParseException.java b/src/main/java/org/openflow/protocol/factory/MessageParseException.java index 328ee583d13c320cb2ceae7c12af8462f0ee8c1b..b685e5d288e45e50544a5288bafc9e10303cedd0 100644 --- a/src/main/java/org/openflow/protocol/factory/MessageParseException.java +++ b/src/main/java/org/openflow/protocol/factory/MessageParseException.java @@ -15,6 +15,7 @@ public class MessageParseException extends Exception { public MessageParseException(String message, Throwable cause) { super(message, cause); + this.setStackTrace(cause.getStackTrace()); } public MessageParseException(String message) { @@ -23,5 +24,6 @@ public class MessageParseException extends Exception { public MessageParseException(Throwable cause) { super(cause); + this.setStackTrace(cause.getStackTrace()); } } diff --git a/src/main/java/org/openflow/protocol/serializers/OFPhysicalPortJSONSerializer.java b/src/main/java/org/openflow/protocol/serializers/OFPhysicalPortJSONSerializer.java deleted file mode 100644 index b847a72c6c59add03167666ab998a4ecbde26005..0000000000000000000000000000000000000000 --- a/src/main/java/org/openflow/protocol/serializers/OFPhysicalPortJSONSerializer.java +++ /dev/null @@ -1,57 +0,0 @@ -/** -* 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 -* not use this file except in compliance with the License. You may obtain -* a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -* License for the specific language governing permissions and limitations -* under the License. -**/ - -package org.openflow.protocol.serializers; - -import java.io.IOException; - -import org.codehaus.jackson.JsonGenerator; -import org.codehaus.jackson.JsonProcessingException; -import org.codehaus.jackson.map.JsonSerializer; -import org.codehaus.jackson.map.SerializerProvider; -import org.openflow.protocol.OFPhysicalPort; -import org.openflow.util.HexString; - -public class OFPhysicalPortJSONSerializer extends JsonSerializer<OFPhysicalPort> { - - /** - * Performs the serialization of a OFPhysicalPort object - */ - @Override - public void serialize(OFPhysicalPort port, JsonGenerator jGen, SerializerProvider serializer) throws IOException, JsonProcessingException { - jGen.writeStartObject(); - jGen.writeNumberField("advertisedFeatures", port.getAdvertisedFeatures()); - jGen.writeNumberField("config", port.getConfig()); - jGen.writeNumberField("currentFeatures", port.getCurrentFeatures()); - jGen.writeStringField("hardwareAddress", HexString.toHexString(port.getHardwareAddress())); - jGen.writeStringField("name", port.getName()); - jGen.writeNumberField("peerFeatures", port.getPeerFeatures()); - jGen.writeNumberField("portNumber", port.getPortNumber()); - jGen.writeNumberField("state", port.getState()); - jGen.writeNumberField("supportedFeatures", port.getSupportedFeatures()); - jGen.writeEndObject(); - } - - /** - * Tells SimpleModule that we are the serializer for OFPhysicalPort - */ - @Override - public Class<OFPhysicalPort> handledType() { - return OFPhysicalPort.class; - } - -} diff --git a/src/test/java/net/floodlightcontroller/flowcache/FlowReconcileMgrTest.java b/src/test/java/net/floodlightcontroller/flowcache/FlowReconcileMgrTest.java index 542b9ccb502431824eea9975719005753a028204..fcf8e67984b925c156f15befe89ac0bc1492aa41 100644 --- a/src/test/java/net/floodlightcontroller/flowcache/FlowReconcileMgrTest.java +++ b/src/test/java/net/floodlightcontroller/flowcache/FlowReconcileMgrTest.java @@ -18,17 +18,6 @@ import org.junit.Test; import org.openflow.protocol.OFStatisticsRequest; import org.openflow.protocol.OFType; -/** - * The Class FlowCacheTest. Tests flow cache operations for - * (a) adding a flow to the flow cache when flow mod is programmed - * (b) Deleting a flow from flow cache when flow mod removal mesg is received - * (c) Reprogramming a flow based on flows queried from flow cache when a - * device is moved. - * (d) Reprogramming a flow based on flows queried from flow cache when a - * link goes down. - * - * @author subrata - */ public class FlowReconcileMgrTest extends FloodlightTestCase { protected MockFloodlightProvider mockFloodlightProvider; @@ -81,7 +70,7 @@ public class FlowReconcileMgrTest extends FloodlightTestCase { flowReconcileMgr.addFlowReconcileListener(r2); flowReconcileMgr.addFlowReconcileListener(r3); - OFMatchReconcile ofmRcIn = flowReconcileMgr.newOFMatchReconcile(); + OFMatchReconcile ofmRcIn = new OFMatchReconcile(); try { flowReconcileMgr.reconcileFlow(ofmRcIn); } catch (RuntimeException e) { diff --git a/src/test/java/org/openflow/protocol/BasicFactoryTest.java b/src/test/java/org/openflow/protocol/BasicFactoryTest.java index 95f61df24963b6116d43c3ee1715bbff591e0d98..05f8e124b1f847598b2346cfbbfad8acbb39fd33 100644 --- a/src/test/java/org/openflow/protocol/BasicFactoryTest.java +++ b/src/test/java/org/openflow/protocol/BasicFactoryTest.java @@ -28,6 +28,7 @@ import org.openflow.util.U16; import junit.framework.TestCase; public class BasicFactoryTest extends TestCase { + public void testCreateAndParse() throws MessageParseException { BasicFactory factory = new BasicFactory(); OFMessage m = factory.getMessage(OFType.HELLO); @@ -46,4 +47,34 @@ public class BasicFactoryTest extends TestCase { TestCase.assertEquals(message.size(), 1); TestCase.assertTrue(message.get(0).getType() == OFType.ECHO_REQUEST); } + + public void testInvalidMsgParse() throws MessageParseException { + BasicFactory factory = new BasicFactory(); + OFMessage m = factory.getMessage(OFType.HELLO); + m.setVersion((byte) 1); + m.setType(OFType.ECHO_REQUEST); + m.setLength(U16.t(16)); + m.setXid(0xdeadbeef); + ChannelBuffer bb = ChannelBuffers.dynamicBuffer(); + m.writeTo(bb); + List<OFMessage> message = factory.parseMessage(bb); + TestCase.assertNull(message); + } + + public void testCurrouptedMsgParse() throws MessageParseException { + BasicFactory factory = new BasicFactory(); + OFMessage m = factory.getMessage(OFType.HELLO); + m.setVersion((byte) 1); + m.setType(OFType.ERROR); + m.setLength(U16.t(8)); + m.setXid(0xdeadbeef); + ChannelBuffer bb = ChannelBuffers.dynamicBuffer(); + m.writeTo(bb); + try { + factory.parseMessage(bb); + } + catch(Exception e) { + TestCase.assertEquals(MessageParseException.class, e.getClass()); + } + } }