Skip to content
Snippets Groups Projects
Commit 8cac6a2e authored by abat's avatar abat
Browse files

Merge into master from pull request #171:

Add flowCacheService interface (https://github.com/floodlight/floodlight/pull/171)
parents 32bb31b9 f120effb
No related branches found
No related tags found
No related merge requests found
Showing
with 594 additions and 2 deletions
......@@ -42,13 +42,13 @@ public interface IDeviceService extends IFloodlightService {
* The source device for the current packet-in, if applicable.
*/
public static final String CONTEXT_SRC_DEVICE =
"com.bigswitch.floodlight.devicemanager.srcDevice";
"net.floodlightcontroller.devicemanager.srcDevice";
/**
* The destination device for the current packet-in, if applicable.
*/
public static final String CONTEXT_DST_DEVICE =
"com.bigswitch.floodlight.devicemanager.dstDevice";
"net.floodlightcontroller.devicemanager.dstDevice";
/**
* A FloodlightContextStore object that can be used to interact with the
......
package net.floodlightcontroller.flowcache;
import java.util.Arrays;
import net.floodlightcontroller.devicemanager.IDevice;
import net.floodlightcontroller.flowcache.IFlowCacheService.FCQueryEvType;
import net.floodlightcontroller.flowcache.IFlowCacheService.FCQueryType;
/**
* The Class FCQueryObj.
*/
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. */
public Short[] vlans;
/** The destination device. */
public IDevice dstDevice;
/** The source device. */
public IDevice srcDevice;
/** The caller name */
public String callerName;
/** Event type that triggered this flow query submission */
public FCQueryEvType evType;
/** The caller opaque data. Returned unchanged in the query response
* via the callback. The type of this object could be different for
* different callers */
public Object callerOpaqueObj;
/**
* Instantiates a new flow cache query object
*/
public FCQueryObj() {
queryType = FCQueryType.UNKNOWN;
}
@Override
public String toString() {
return "FCQueryObj [fcQueryCaller=" + fcQueryHandler
+ ", queryType=" + queryType + ", applInstName="
+ applInstName + ", vlans=" + Arrays.toString(vlans)
+ ", dstDevice=" + dstDevice + ", srcDevice="
+ srcDevice + ", callerName=" + callerName + ", evType="
+ evType + ", callerOpaqueObj=" + callerOpaqueObj + "]";
}
}
package net.floodlightcontroller.flowcache;
import java.util.ArrayList;
/**
* Object to return flows in response to a query message to BigFlowCache.
* This object is passed in the flowQueryRespHandler() callback.
*/
public class FlowCacheQueryResp {
/** query object provided by the caller, returned unchanged. */
public FCQueryObj queryObj;
/**
* Set to true if more flows could be returned for this query in
* additional callbacks. Set of false in the last callback for the
* query.
*/
public boolean moreFlag;
/**
* The flow list. If there are large number of flows to be returned
* then they may be returned in multiple callbacks.
*/
public ArrayList<QRFlowCacheObj> qrFlowCacheObjList;
/**
* Instantiates a new big flow cache query response.
*
* @param query the flow cache query object as given by the caller of
* flow cache submit query API.
*/
public FlowCacheQueryResp(FCQueryObj query) {
qrFlowCacheObjList = new ArrayList<QRFlowCacheObj>();
queryObj = query;
moreFlag = false;
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
String s = queryObj.toString();
if (moreFlag) {
s += "; moreFlasg=True";
} else {
s += "; moreFlag=False";
}
s += "; FlowCount=" + Integer.toString(qrFlowCacheObjList.size());
return s;
}
}
......@@ -10,6 +10,8 @@ import net.floodlightcontroller.core.module.FloodlightModuleException;
import net.floodlightcontroller.core.module.IFloodlightModule;
import net.floodlightcontroller.core.module.IFloodlightService;
import net.floodlightcontroller.core.util.ListenerDispatcher;
import net.floodlightcontroller.devicemanager.IDevice;
import net.floodlightcontroller.flowcache.IFlowCacheService.FCQueryEvType;
import net.floodlightcontroller.flowcache.IFlowReconcileListener;
import net.floodlightcontroller.flowcache.OFMatchReconcile;
......@@ -86,6 +88,31 @@ public class FlowReconcileManager
}
}
@Override
public void updateFlowForDestinationDevice(IDevice device, FCQueryEvType fcEvType){
// NO-OP
}
@Override
public void updateFlowForSourceDevice(IDevice device, FCQueryEvType fcEvType){
// NO-OP
}
@Override
public void flowQueryGenericHandler(FlowCacheQueryResp flowResp) {
if (flowResp.queryObj.evType != FCQueryEvType.GET) {
OFMatchReconcile ofmRc = newOFMatchReconcile();
/* Re-provision these flows */
for (QRFlowCacheObj entry : flowResp.qrFlowCacheObjList) {
/* reconcile the flows in entry */
entry.toOFMatchReconcile(ofmRc, flowResp.queryObj.applInstName,
OFMatchReconcile.ReconcileAction.UPDATE_PATH);
reconcileFlow(ofmRc);
}
}
return;
}
// IFloodlightModule
@Override
......
package net.floodlightcontroller.flowcache;
import org.openflow.protocol.OFMatchWithSwDpid;
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;
/**
* The Interface IFlowCache.
* <p>
* public interface APIs to Big Switch Flow-Cache Service. Flow-Cache maintains
* the network-level flows that are currently deployed in the underlying
* network. The flow cache can be queried using various filters by using the
* corresponding APIs.
*
* @author subrata
*
*/
public interface IFlowCacheService extends IFloodlightService {
public static final String FLOWCACHE_APP_NAME =
"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
* query. The callerOpaqueObj can be keyed based on this event type
*/
public static enum FCQueryEvType {
/** The GET query. Flows need not be reconciled for this query type */
GET,
/** A new App was added. */
APP_ADDED,
/** An App was deleted. */
APP_DELETED,
/** Interface rule of an app was modified */
APP_INTERFACE_RULE_CHANGED,
/** Some App configuration was changed */
APP_CONFIG_CHANGED,
/** An ACL was added */
ACL_ADDED,
/** An ACL was deleted */
ACL_DELETED,
/** An ACL rule was added */
ACL_RULE_ADDED,
/** An ACL rule was deleted */
ACL_RULE_DELETED,
/** ACL configuration was changed */
ACL_CONFIG_CHANGED,
/** device had moved to a different port in the network */
DEVICE_MOVED,
/** device's property had changed, such as tag assignment */
DEVICE_PROPERTY_CHANGED,
/** Link down */
LINK_DOWN,
/** Periodic scan of switch flow table */
PERIODIC_SCAN,
}
/**
* A FloodlightContextStore object that can be used to interact with the
* FloodlightContext information about flowCache.
*/
public static final FloodlightContextStore<String> fcStore =
new FloodlightContextStore<String>();
/**
* Submit a flow cache query with query parameters specified in FCQueryObj
* object. The query object can be created using one of the newFCQueryObj
* helper functions in IFlowCache interface.
* <p>
* The queried flows are returned via the flowQueryRespHandler() callback
* that the caller must implement. The caller can match the query with
* the response using unique callerOpaqueData which remains unchanged
* in the request and response callback.
*
* @see com.bigswitch.floodlight.flowcache#flowQueryRespHandler
* @param query the flow cache query object as input
*
*/
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
* from the cache.
*
* @param switchDpid Data-path identifier of the source switch
*/
public void deactivateFlowCacheBySwitch(long switchDpid);
/**
* Deletes all flows in the flow cache for which the source switch
* matches the given switchDpid.
*
* @param switchDpid Data-path identifier of the source switch
*/
public void deleteFlowCacheBySwitch(long switchDpid);
/**
* Add a flow to the flow-cache - called when a flow-mod is about to be
* written to a set of switches. If it returns false then it should not
* be written to the switches. If it returns true then the cookie returned
* should be used for the flow mod sent to the switches.
*
* @param appInstName Application instance name
* @param ofm openflow match object
* @param cookie openflow-mod cookie
* @param swPort SwitchPort object
* @param priority openflow match priority
* @param action action taken on the matched packets (PERMIT or DENY)
* @return true: flow should be written to the switch(es)
* false: flow should not be written to the switch(es). false is
* returned, for example, when the flow was recently
* written to the flow-cache and hence it is dampened to
* avoid frequent writes of the same flow to the switches
* This case can typically arise for the flows written at the
* internal ports as they are heavily wild-carded.
*/
public boolean addFlow(String appInstName, OFMatchWithSwDpid ofm,
Long cookie, long srcSwDpid,
short inPort, short priority, byte action);
/**
* Add a flow to the flow-cache - called when a flow-mod is about to be
* written to a set of switches. If it returns false then it should not
* be written to the switches. If it returns true then the cookie returned
* should be used for the flow mod sent to the switches.
*
* @param cntx the cntx
* @param ofm the ofm
* @param cookie the cookie
* @param swPort the sw port
* @param priority the priority
* @param action the action
* @return true: flow should be written to the switch(es)
* false: flow should not be written to the switch(es). false is
* returned, for example, when the flow was recently
* written to the flow-cache and hence it is dampened to
* avoid frequent writes of the same flow to the switches
* This case can typically arise for the flows written at the
* internal ports as they are heavily wild-carded.
*/
public boolean addFlow(FloodlightContext cntx, OFMatchWithSwDpid ofm,
Long cookie, SwitchPort swPort,
short priority, byte action);
/**
* Move the specified flow from its current application instance to a
* different application instance. This API can be used when a flow moves
* to a different application instance when the application instance
* configuration changes or when a device moves to a different part in
* the network that belongs to a different application instance.
* <p>
* Note that, if the flow was not found in the current application
* instance then the flow is not moved to the new application instance.
*
* @param ofMRc the object containing the flow match and new application
* instance name.
* @return true is the flow was found in the flow cache in the current
* application instance; false if the flow was not found in the flow-cache
* in the current application instance.
*/
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
*/
public void deleteAllFlowsAtASourceSwitch(IOFSwitch sw);
/**
* Post a request to update flowcache from a switch.
* This is an asynchronous operation.
* It queries the switch for stats and updates the flowcache asynchronously
* with the response.
* @param swDpid
* @param delay_ms
*/
public void querySwitchFlowTable(long swDpid);
}
package net.floodlightcontroller.flowcache;
public interface IFlowQueryHandler {
/**
* This callback function is called in response to a flow query request
* submitted to the flow cache service. The module handling this callback
* can be different from the one that submitted the query. In the flow
* query object used for submitting the flow query, the identity of the
* callback handler is passed. When flow cache service has all or some
* of the flows that needs to be returned then this callback is called
* for the appropriate module. The respone contains a boolean more flag
* that indicates if there are additional flows that may be returned
* via additional callback calls.
*
* @param resp the response object containing the original flow query
* object, partial or complete list of flows that we queried and some
* metadata such as the more flag described aboce.
*
*/
public void flowQueryRespHandler(FlowCacheQueryResp resp);
}
......@@ -5,6 +5,8 @@
package net.floodlightcontroller.flowcache;
import net.floodlightcontroller.core.module.IFloodlightService;
import net.floodlightcontroller.devicemanager.IDevice;
import net.floodlightcontroller.flowcache.IFlowCacheService.FCQueryEvType;
public interface IFlowReconcileService extends IFloodlightService {
/**
......@@ -32,5 +34,36 @@ public interface IFlowReconcileService extends IFloodlightService {
* @param ofmRcIn the ofm rc in
*/
public void reconcileFlow(OFMatchReconcile ofmRcIn);
/**
* Updates the flows to a device after the device moved to a new location
* <p>
* Queries the flow-cache to get all the flows destined to the given device.
* Reconciles each of these flows by potentially reprogramming them to its
* new attachment point
*
* @param device device that has moved
* @param fcEvType Event type that triggered the update
*
*/
public void updateFlowForDestinationDevice(IDevice device, FCQueryEvType fcEvType);
/**
* Updates the flows from a device
* <p>
* Queries the flow-cache to get all the flows source from the given device.
* Reconciles each of these flows by potentially reprogramming them to its
* new attachment point
*
* @param device device where the flow originates
* @param fcEvType Event type that triggered the update
*
*/
public void updateFlowForSourceDevice(IDevice device, FCQueryEvType fcEvType);
/**
* Generic flow query handler to insert FlowMods into the reconcile pipeline.
* @param flowResp
*/
public void flowQueryGenericHandler(FlowCacheQueryResp flowResp);
}
package net.floodlightcontroller.flowcache;
public class PendingSwRespKey {
long swDpid;
int transId;
public PendingSwRespKey(long swDpid, int transId) {
this.swDpid = swDpid;
this.transId = transId;
}
@Override
public int hashCode() {
final int prime = 97;
Long dpid = swDpid;
Integer tid = transId;
return (tid.hashCode()*prime + dpid.hashCode());
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof PendingSwRespKey)) {
return false;
}
PendingSwRespKey other = (PendingSwRespKey) obj;
if ((swDpid != other.swDpid) || (transId != other.transId)) {
return false;
}
return true;
}
@Override
public String toString() {
return Long.toHexString(swDpid)+","+Integer.toString(transId);
}
}
package net.floodlightcontroller.flowcache;
import net.floodlightcontroller.flowcache.IFlowCacheService.FCQueryEvType;
/**
* The Class PendingSwitchResp. This object is used to track the pending
* responses to switch flow table queries.
*/
public class PendingSwitchResp {
protected FCQueryEvType evType;
public PendingSwitchResp(
FCQueryEvType evType) {
this.evType = evType;
}
public FCQueryEvType getEvType() {
return evType;
}
public void setEvType(FCQueryEvType evType) {
this.evType = evType;
}
}
package net.floodlightcontroller.flowcache;
import org.openflow.protocol.OFMatchWithSwDpid;
/**
* Used in BigFlowCacheQueryResp as query result.
* Used to return one flow when queried by one of the big flow cache APIs.
* One of these QRFlowCacheObj is returned for each combination of
* priority and action.
*
* @author subrata
*/
public class QRFlowCacheObj {
/** The open flow match object. */
public OFMatchWithSwDpid ofmWithSwDpid;
/** The flow-mod priority. */
public short priority;
/** flow-mod cookie */
public long cookie;
/** The action - PERMIT or DENY. */
public byte action;
/** The reserved byte to align with 8 bytes. */
public byte reserved;
/**
* Instantiates a new flow cache query object.
*
* @param priority the priority
* @param action the action
*/
public QRFlowCacheObj(short priority, byte action, long cookie) {
ofmWithSwDpid = new OFMatchWithSwDpid();
this.action = action;
this.priority = priority;
this.cookie = cookie;
}
/**
* Populate a given OFMatchReconcile object from the values of this
* class.
*
* @param ofmRc the given OFMatchReconcile object
* @param appInstName the application instance name
* @param rcAction the reconcile action
*/
public void toOFMatchReconcile(OFMatchReconcile ofmRc,
String appInstName, OFMatchReconcile.ReconcileAction rcAction) {
ofmRc.ofmWithSwDpid = ofmWithSwDpid; // not copying
ofmRc.appInstName = appInstName;
ofmRc.rcAction = rcAction;
ofmRc.priority = priority;
ofmRc.cookie = cookie;
ofmRc.action = action;
}
@Override
public String toString() {
String str = "ofmWithSwDpid: " + this.ofmWithSwDpid.toString() + " ";
str += "priority: " + this.priority + " ";
str += "cookie: " + this.cookie + " ";
str += "action: " + this.action + " ";
str += "reserved: " + this.reserved + " ";
return str;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment