Skip to content
Snippets Groups Projects
Commit c98b4a10 authored by Gregor Maier's avatar Gregor Maier
Browse files

Don't allow matching on invalid fields in OFMatch BVS-525

parent 493a0c3c
No related branches found
No related tags found
No related merge requests found
......@@ -45,13 +45,13 @@ import org.openflow.protocol.OFType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FlowReconcileManager
public class FlowReconcileManager
implements IFloodlightModule, IFlowReconcileService {
/** The logger. */
private static Logger logger =
LoggerFactory.getLogger(FlowReconcileManager.class);
/** Reference to dependent modules */
protected IThreadPoolService threadPool;
protected ICounterStoreService counterStore;
......@@ -67,28 +67,28 @@ public class FlowReconcileManager
/** A FIFO queue to keep all outstanding flows for reconciliation */
PriorityPendingQueue <OFMatchReconcile> flowQueue;
/** Asynchronous task to feed the flowReconcile pipeline */
protected SingletonTask flowReconcileTask;
String controllerPktInCounterName;
protected SimpleCounter lastPacketInCounter;
protected final static int MAX_SYSTEM_LOAD_PER_SECOND = 10000;
/** a minimum flow reconcile rate so that it won't stave */
protected final static int MIN_FLOW_RECONCILE_PER_SECOND = 200;
/** start flow reconcile in 10ms after a new reconcile request is received.
* The max delay is 1 second. */
protected final static int FLOW_RECONCILE_DELAY_MILLISEC = 10;
protected Date lastReconcileTime;
/** Config to enable or disable flowReconcile */
protected static final String EnableConfigKey = "enable";
protected boolean flowReconcileEnabled;
public AtomicInteger flowReconcileThreadRunCount;
@Override
public synchronized void addFlowReconcileListener(
IFlowReconcileListener listener) {
......@@ -111,25 +111,26 @@ public class FlowReconcileManager
IFlowReconcileListener listener) {
flowReconcileListeners.removeListener(listener);
}
@Override
public synchronized void clearFlowReconcileListeners() {
flowReconcileListeners.clearListeners();
}
/**
* Add to-be-reconciled flow to the queue.
*
* @param ofmRcIn the ofm rc in
*/
@Override
public void reconcileFlow(OFMatchReconcile ofmRcIn, EventPriority priority) {
if (ofmRcIn == null) return;
// Make a copy before putting on the queue.
OFMatchReconcile myOfmRc = new OFMatchReconcile(ofmRcIn);
flowQueue.offer(myOfmRc, priority);
Date currTime = new Date();
long delay = 0;
......@@ -143,28 +144,28 @@ public class FlowReconcileManager
delay = FLOW_RECONCILE_DELAY_MILLISEC;
}
flowReconcileTask.reschedule(delay, TimeUnit.MILLISECONDS);
if (logger.isTraceEnabled()) {
logger.trace("Reconciling flow: {}, total: {}",
myOfmRc.toString(), flowQueue.size());
}
}
// IFloodlightModule
@Override
public Collection<Class<? extends IFloodlightService>> getModuleServices() {
Collection<Class<? extends IFloodlightService>> l =
Collection<Class<? extends IFloodlightService>> l =
new ArrayList<Class<? extends IFloodlightService>>();
l.add(IFlowReconcileService.class);
return l;
}
@Override
public Map<Class<? extends IFloodlightService>, IFloodlightService>
public Map<Class<? extends IFloodlightService>, IFloodlightService>
getServiceImpls() {
Map<Class<? extends IFloodlightService>,
IFloodlightService> m =
IFloodlightService> m =
new HashMap<Class<? extends IFloodlightService>,
IFloodlightService>();
m.put(IFlowReconcileService.class, this);
......@@ -172,9 +173,9 @@ public class FlowReconcileManager
}
@Override
public Collection<Class<? extends IFloodlightService>>
public Collection<Class<? extends IFloodlightService>>
getModuleDependencies() {
Collection<Class<? extends IFloodlightService>> l =
Collection<Class<? extends IFloodlightService>> l =
new ArrayList<Class<? extends IFloodlightService>>();
l.add(IThreadPoolService.class);
l.add(ICounterStoreService.class);
......@@ -188,9 +189,9 @@ public class FlowReconcileManager
counterStore = context.getServiceImpl(ICounterStoreService.class);
flowQueue = new PriorityPendingQueue<OFMatchReconcile>();
flowReconcileListeners =
flowReconcileListeners =
new ListenerDispatcher<OFType, IFlowReconcileListener>();
Map<String, String> configParam = context.getConfigParams(this);
String enableValue = configParam.get(EnableConfigKey);
// Set flowReconcile default to true
......@@ -199,7 +200,7 @@ public class FlowReconcileManager
enableValue.equalsIgnoreCase("false")) {
flowReconcileEnabled = false;
}
flowReconcileThreadRunCount = new AtomicInteger(0);
lastReconcileTime = new Date(0);
logger.debug("FlowReconcile is {}", flowReconcileEnabled);
......@@ -219,23 +220,21 @@ public class FlowReconcileManager
TimeUnit.MILLISECONDS);
}
} catch (Exception e) {
logger.warn("Exception in doReconcile(): {}",
e.getMessage());
e.printStackTrace();
logger.warn("Exception in doReconcile(): {}", e);
}
}
});
String packetInName = OFType.PACKET_IN.toClass().getName();
packetInName = packetInName.substring(packetInName.lastIndexOf('.')+1);
packetInName = packetInName.substring(packetInName.lastIndexOf('.')+1);
// Construct controller counter for the packet_in
controllerPktInCounterName =
CounterStore.createCounterName(ICounterStoreService.CONTROLLER_NAME,
CounterStore.createCounterName(ICounterStoreService.CONTROLLER_NAME,
-1,
packetInName);
}
protected void updateFlush() {
// No-OP
}
......@@ -248,13 +247,13 @@ public class FlowReconcileManager
if (!flowReconcileEnabled) {
return false;
}
// Record the execution time.
lastReconcileTime = new Date();
ArrayList<OFMatchReconcile> ofmRcList =
new ArrayList<OFMatchReconcile>();
// Get the maximum number of flows that can be reconciled.
int reconcileCapacity = getCurrentCapacity();
if (logger.isTraceEnabled()) {
......@@ -272,7 +271,7 @@ public class FlowReconcileManager
break;
}
}
// Run the flow through all the flow reconcile listeners
IFlowReconcileListener.Command retCmd;
if (ofmRcList.size() > 0) {
......@@ -284,7 +283,7 @@ public class FlowReconcileManager
}
return false;
}
for (IFlowReconcileListener flowReconciler :
flowReconcileListeners.getOrderedListeners()) {
if (logger.isTraceEnabled())
......@@ -305,7 +304,7 @@ public class FlowReconcileManager
logger.trace("No flow to be reconciled.");
}
}
// Return true if there are more flows to be reconciled
if (flowQueue.isEmpty()) {
return false;
......@@ -317,10 +316,10 @@ public class FlowReconcileManager
return true;
}
}
/**
* Compute the maximum number of flows to be reconciled.
*
*
* It computes the packetIn increment from the counter values in
* the counter store;
* Then computes the rate based on the elapsed time
......@@ -339,7 +338,7 @@ public class FlowReconcileManager
counterStore.getCounter(controllerPktInCounterName);
int minFlows = MIN_FLOW_RECONCILE_PER_SECOND *
FLOW_RECONCILE_DELAY_MILLISEC / 1000;
// If no packetInCounter, then there shouldn't be any flow.
if (pktInCounter == null ||
pktInCounter.getCounterDate() == null ||
......@@ -348,7 +347,7 @@ public class FlowReconcileManager
controllerPktInCounterName);
return minFlows;
}
// Haven't get any counter yet.
if (lastPacketInCounter == null) {
logger.debug("First time get the count for {}",
......@@ -357,9 +356,9 @@ public class FlowReconcileManager
SimpleCounter.createCounter(pktInCounter);
return minFlows;
}
int pktInRate = getPktInRate(pktInCounter, new Date());
// Update the last packetInCounter
lastPacketInCounter = (SimpleCounter)
SimpleCounter.createCounter(pktInCounter);
......@@ -369,20 +368,20 @@ public class FlowReconcileManager
capacity = (MAX_SYSTEM_LOAD_PER_SECOND - pktInRate)
* FLOW_RECONCILE_DELAY_MILLISEC / 1000;
}
if (logger.isTraceEnabled()) {
logger.trace("Capacity is {}", capacity);
}
return capacity;
}
protected int getPktInRate(ICounter newCnt, Date currentTime) {
if (newCnt == null ||
newCnt.getCounterDate() == null ||
newCnt.getCounterValue() == null) {
return 0;
}
// Somehow the system time is messed up. return max packetIn rate
// to reduce the system load.
if (newCnt.getCounterDate().before(
......@@ -392,14 +391,14 @@ public class FlowReconcileManager
lastPacketInCounter.getCounterDate());
return MAX_SYSTEM_LOAD_PER_SECOND;
}
long elapsedTimeInSecond = (currentTime.getTime() -
lastPacketInCounter.getCounterDate().getTime()) / 1000;
if (elapsedTimeInSecond == 0) {
// This should never happen. Check to avoid division by zero.
return 0;
}
long diff = 0;
switch (newCnt.getCounterValue().getType()) {
case LONG:
......@@ -412,7 +411,7 @@ public class FlowReconcileManager
diff = newLong - oldLong;
}
break;
case DOUBLE:
double newDouble = newCnt.getCounterValue().getDouble();
double oldDouble = lastPacketInCounter.getCounterValue().getDouble();
......@@ -424,7 +423,7 @@ public class FlowReconcileManager
}
break;
}
return (int)(diff/elapsedTimeInSecond);
}
}
......
......@@ -32,7 +32,7 @@ import org.openflow.util.U8;
/**
* Represents an ofp_match structure
*
*
* @author David Erickson (daviderickson@cs.stanford.edu)
* @author Rob Sherwood (rob.sherwood@stanford.edu)
*/
......@@ -137,7 +137,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Get dl_dst
*
*
* @return an arrays of bytes
*/
public byte[] getDataLayerDestination() {
......@@ -146,7 +146,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Set dl_dst
*
*
* @param dataLayerDestination
*/
public OFMatch setDataLayerDestination(byte[] dataLayerDestination) {
......@@ -156,7 +156,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Set dl_dst, but first translate to byte[] using HexString
*
*
* @param mac
* A colon separated string of 6 pairs of octets, e..g.,
* "00:17:42:EF:CD:8D"
......@@ -174,7 +174,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Get dl_src
*
*
* @return an array of bytes
*/
public byte[] getDataLayerSource() {
......@@ -183,7 +183,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Set dl_src
*
*
* @param dataLayerSource
*/
public OFMatch setDataLayerSource(byte[] dataLayerSource) {
......@@ -193,7 +193,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Set dl_src, but first translate to byte[] using HexString
*
*
* @param mac
* A colon separated string of 6 pairs of octets, e..g.,
* "00:17:42:EF:CD:8D"
......@@ -211,7 +211,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Get dl_type
*
*
* @return ether_type
*/
public short getDataLayerType() {
......@@ -220,7 +220,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Set dl_type
*
*
* @param dataLayerType
*/
public OFMatch setDataLayerType(short dataLayerType) {
......@@ -230,7 +230,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Get dl_vlan
*
*
* @return vlan tag; VLAN_NONE == no tag
*/
public short getDataLayerVirtualLan() {
......@@ -239,7 +239,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Set dl_vlan
*
*
* @param dataLayerVirtualLan
*/
public OFMatch setDataLayerVirtualLan(short dataLayerVirtualLan) {
......@@ -249,7 +249,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Get dl_vlan_pcp
*
*
* @return
*/
public byte getDataLayerVirtualLanPriorityCodePoint() {
......@@ -258,7 +258,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Set dl_vlan_pcp
*
*
* @param pcp
*/
public OFMatch setDataLayerVirtualLanPriorityCodePoint(byte pcp) {
......@@ -268,7 +268,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Get in_port
*
*
* @return
*/
public short getInputPort() {
......@@ -277,7 +277,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Set in_port
*
*
* @param inputPort
*/
public OFMatch setInputPort(short inputPort) {
......@@ -287,7 +287,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Get nw_dst
*
*
* @return
*/
public int getNetworkDestination() {
......@@ -296,7 +296,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Set nw_dst
*
*
* @param networkDestination
*/
public OFMatch setNetworkDestination(int networkDestination) {
......@@ -309,7 +309,7 @@ public class OFMatch implements Cloneable, Serializable {
* bits in the IP destination field. NOTE: this returns the number of bits
* that are fixed, i.e., like CIDR, not the number of bits that are free
* like OpenFlow encodes.
*
*
* @return a number between 0 (matches all IPs) and 63 ( 32>= implies exact
* match)
*/
......@@ -323,7 +323,7 @@ public class OFMatch implements Cloneable, Serializable {
* bits in the IP destination field. NOTE: this returns the number of bits
* that are fixed, i.e., like CIDR, not the number of bits that are free
* like OpenFlow encodes.
*
*
* @return a number between 0 (matches all IPs) and 32 (exact match)
*/
public int getNetworkSourceMaskLen() {
......@@ -333,7 +333,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Get nw_proto
*
*
* @return
*/
public byte getNetworkProtocol() {
......@@ -342,7 +342,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Set nw_proto
*
*
* @param networkProtocol
*/
public OFMatch setNetworkProtocol(byte networkProtocol) {
......@@ -352,7 +352,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Get nw_src
*
*
* @return
*/
public int getNetworkSource() {
......@@ -361,7 +361,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Set nw_src
*
*
* @param networkSource
*/
public OFMatch setNetworkSource(int networkSource) {
......@@ -372,7 +372,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Get nw_tos OFMatch stores the ToS bits as top 6-bits, so right shift by 2
* bits before returning the value
*
*
* @return : 6-bit DSCP value (0-63)
*/
public byte getNetworkTypeOfService() {
......@@ -382,7 +382,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Set nw_tos OFMatch stores the ToS bits as top 6-bits, so left shift by 2
* bits before storing the value
*
*
* @param networkTypeOfService
* : 6-bit DSCP value (0-63)
*/
......@@ -393,7 +393,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Get tp_dst
*
*
* @return
*/
public short getTransportDestination() {
......@@ -402,7 +402,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Set tp_dst
*
*
* @param transportDestination
*/
public OFMatch setTransportDestination(short transportDestination) {
......@@ -412,7 +412,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Get tp_src
*
*
* @return
*/
public short getTransportSource() {
......@@ -421,7 +421,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Set tp_src
*
*
* @param transportSource
*/
public OFMatch setTransportSource(short transportSource) {
......@@ -431,7 +431,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Get wildcards
*
*
* @return
*/
public int getWildcards() {
......@@ -440,7 +440,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Get wildcards
*
*
* @return
*/
public Wildcards getWildcardObj() {
......@@ -449,7 +449,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Set wildcards
*
*
* @param wildcards
*/
public OFMatch setWildcards(int wildcards) {
......@@ -468,7 +468,7 @@ public class OFMatch implements Cloneable, Serializable {
* specified packet. Must specify the input port, to ensure that
* this.in_port is set correctly. Specify OFPort.NONE or OFPort.ANY if input
* port not applicable or available
*
*
* @param packetData
* The packet's data
* @param inputPort
......@@ -550,6 +550,11 @@ public class OFMatch implements Cloneable, Serializable {
}
break;
default:
// Not ARP or IP. Wildcard NW_DST and NW_SRC
this.wildcards |= OFPFW_NW_DST_ALL |
OFPFW_NW_SRC_ALL |
OFPFW_NW_PROTO |
OFPFW_NW_TOS;
setNetworkTypeOfService((byte) 0);
setNetworkProtocol((byte) 0);
setNetworkSource(0);
......@@ -580,6 +585,8 @@ public class OFMatch implements Cloneable, Serializable {
this.transportDestination = packetDataBB.getShort();
break;
default:
// Unknown network proto.
this.wildcards |= OFPFW_TP_DST | OFPFW_TP_SRC;
setTransportDestination((short) 0);
setTransportSource((short) 0);
break;
......@@ -589,7 +596,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Read this message off the wire from the specified ByteBuffer
*
*
* @param data
*/
public void readFrom(ChannelBuffer data) {
......@@ -615,7 +622,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Write this message's binary format to the specified ByteBuffer
*
*
* @param data
*/
public void writeTo(ChannelBuffer data) {
......@@ -734,8 +741,8 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Output a dpctl-styled string, i.e., only list the elements that are not
* wildcarded A match-everything OFMatch outputs "OFMatch[]"
*
* @return
*
* @return
* "OFMatch[dl_src:00:20:01:11:22:33,nw_src:192.168.0.0/24,tp_dst:80]"
*/
@Override
......@@ -815,6 +822,47 @@ public class OFMatch implements Cloneable, Serializable {
return "OFMatch[" + str + "]";
}
/**
* Return a string including all match fields, regardless whether they
* are wildcarded or not.
*/
public String toStringUnmasked() {
String str = "";
// l1
str += STR_IN_PORT + "=" + U16.f(this.inputPort);
// l2
str += "," + STR_DL_DST + "="
+ HexString.toHexString(this.dataLayerDestination);
str += "," + STR_DL_SRC + "="
+ HexString.toHexString(this.dataLayerSource);
str += "," + STR_DL_TYPE + "=0x"
+ Integer.toHexString(U16.f(this.dataLayerType));
str += "," + STR_DL_VLAN + "=0x"
+ Integer.toHexString(U16.f(this.dataLayerVirtualLan));
str += "," + STR_DL_VLAN_PCP + "="
+ Integer.toHexString(U8.f(this.dataLayerVirtualLanPriorityCodePoint));
// l3
str += "," + STR_NW_DST + "="
+ cidrToString(networkDestination,
getNetworkDestinationMaskLen());
str += "," + STR_NW_SRC + "="
+ cidrToString(networkSource,
getNetworkSourceMaskLen());
str += "," + STR_NW_PROTO + "=" + this.networkProtocol;
str += "," + STR_NW_TOS + "=" + this.getNetworkTypeOfService();
// l4
str += "," + STR_TP_DST + "=" + this.transportDestination;
str += "," + STR_TP_SRC + "=" + this.transportSource;
// wildcards
str += ", wildcards=" + debugWildCards(wildcards);
return "OFMatch[" + str + "]";
}
/**
* debug a set of wildcards
*/
......@@ -908,7 +956,7 @@ public class OFMatch implements Cloneable, Serializable {
* <p>
* The CIDR-style netmasks assume 32 netmask if none given, so:
* "128.8.128.118/32" is the same as "128.8.128.118"
*
*
* @param match
* a key=value comma separated string, e.g.
* "in_port=5,ip_dst=192.168.0.0/16,tp_src=80"
......@@ -999,7 +1047,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Set the networkSource or networkDestionation address and their wildcards
* from the CIDR string
*
*
* @param cidr
* "192.168.0.0/16" or "172.16.1.5"
* @param which
......
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