Merge branch 'master' of ssh://gerrit.onlab.us:29418/onos-next
diff --git a/cli/src/main/java/org/onlab/onos/cli/net/FlowRuleStatusCompleter.java b/cli/src/main/java/org/onlab/onos/cli/net/FlowRuleStatusCompleter.java
index 134d995..d8c795a 100644
--- a/cli/src/main/java/org/onlab/onos/cli/net/FlowRuleStatusCompleter.java
+++ b/cli/src/main/java/org/onlab/onos/cli/net/FlowRuleStatusCompleter.java
@@ -5,7 +5,7 @@
import org.apache.karaf.shell.console.Completer;
import org.apache.karaf.shell.console.completer.StringsCompleter;
-import org.onlab.onos.net.flow.FlowRule.FlowRuleState;
+import org.onlab.onos.net.flow.FlowEntry.FlowEntryState;
/**
* Device ID completer.
@@ -16,7 +16,7 @@
// Delegate string completer
StringsCompleter delegate = new StringsCompleter();
- FlowRuleState[] states = FlowRuleState.values();
+ FlowEntryState[] states = FlowEntryState.values();
SortedSet<String> strings = delegate.getStrings();
for (int i = 0; i < states.length; i++) {
strings.add(states[i].toString().toLowerCase());
diff --git a/cli/src/main/java/org/onlab/onos/cli/net/FlowsListCommand.java b/cli/src/main/java/org/onlab/onos/cli/net/FlowsListCommand.java
index d49ae6e..8b6cefc 100644
--- a/cli/src/main/java/org/onlab/onos/cli/net/FlowsListCommand.java
+++ b/cli/src/main/java/org/onlab/onos/cli/net/FlowsListCommand.java
@@ -13,8 +13,8 @@
import org.onlab.onos.net.Device;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.device.DeviceService;
-import org.onlab.onos.net.flow.FlowRule;
-import org.onlab.onos.net.flow.FlowRule.FlowRuleState;
+import org.onlab.onos.net.flow.FlowEntry;
+import org.onlab.onos.net.flow.FlowEntry.FlowEntryState;
import org.onlab.onos.net.flow.FlowRuleService;
import com.google.common.collect.Maps;
@@ -45,7 +45,7 @@
protected void execute() {
DeviceService deviceService = get(DeviceService.class);
FlowRuleService service = get(FlowRuleService.class);
- Map<Device, List<FlowRule>> flows = getSortedFlows(deviceService, service);
+ Map<Device, List<FlowEntry>> flows = getSortedFlows(deviceService, service);
for (Device d : flows.keySet()) {
printFlows(d, flows.get(d));
}
@@ -57,12 +57,12 @@
* @param service device service
* @return sorted device list
*/
- protected Map<Device, List<FlowRule>> getSortedFlows(DeviceService deviceService, FlowRuleService service) {
- Map<Device, List<FlowRule>> flows = Maps.newHashMap();
- List<FlowRule> rules;
- FlowRuleState s = null;
+ protected Map<Device, List<FlowEntry>> getSortedFlows(DeviceService deviceService, FlowRuleService service) {
+ Map<Device, List<FlowEntry>> flows = Maps.newHashMap();
+ List<FlowEntry> rules;
+ FlowEntryState s = null;
if (state != null && !state.equals("any")) {
- s = FlowRuleState.valueOf(state.toUpperCase());
+ s = FlowEntryState.valueOf(state.toUpperCase());
}
Iterable<Device> devices = uri == null ? deviceService.getDevices() :
Collections.singletonList(deviceService.getDevice(DeviceId.deviceId(uri)));
@@ -71,7 +71,7 @@
rules = newArrayList(service.getFlowEntries(d.id()));
} else {
rules = newArrayList();
- for (FlowRule f : service.getFlowEntries(d.id())) {
+ for (FlowEntry f : service.getFlowEntries(d.id())) {
if (f.state().equals(s)) {
rules.add(f);
}
@@ -88,13 +88,13 @@
* @param d the device
* @param flows the set of flows for that device.
*/
- protected void printFlows(Device d, List<FlowRule> flows) {
+ protected void printFlows(Device d, List<FlowEntry> flows) {
print("Device: " + d.id());
if (flows == null | flows.isEmpty()) {
print(" %s", "No flows.");
return;
}
- for (FlowRule f : flows) {
+ for (FlowEntry f : flows) {
print(FMT, Long.toHexString(f.id().value()), f.state(), f.bytes(),
f.packets(), f.life(), f.priority());
print(SFMT, f.selector().criteria());
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/DefaultFlowEntry.java b/core/api/src/main/java/org/onlab/onos/net/flow/DefaultFlowEntry.java
new file mode 100644
index 0000000..5a0f55b
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/DefaultFlowEntry.java
@@ -0,0 +1,111 @@
+package org.onlab.onos.net.flow;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import org.onlab.onos.net.DeviceId;
+import org.slf4j.Logger;
+
+public class DefaultFlowEntry extends DefaultFlowRule implements FlowEntry {
+
+ private final Logger log = getLogger(getClass());
+
+ private long life;
+ private long packets;
+ private long bytes;
+ private FlowEntryState state;
+
+ private long lastSeen = -1;
+
+
+ public DefaultFlowEntry(DeviceId deviceId, TrafficSelector selector,
+ TrafficTreatment treatment, int priority, FlowEntryState state,
+ long life, long packets, long bytes, long flowId,
+ int timeout) {
+ super(deviceId, selector, treatment, priority, flowId, timeout);
+ this.state = state;
+ this.life = life;
+ this.packets = packets;
+ this.bytes = bytes;
+ this.lastSeen = System.currentTimeMillis();
+ }
+
+ public DefaultFlowEntry(FlowRule rule, FlowEntryState state,
+ long life, long packets, long bytes) {
+ super(rule);
+ this.state = state;
+ this.life = life;
+ this.packets = packets;
+ this.bytes = bytes;
+ this.lastSeen = System.currentTimeMillis();
+ }
+
+ public DefaultFlowEntry(FlowRule rule) {
+ super(rule);
+ this.state = FlowEntryState.PENDING_ADD;
+ this.life = 0;
+ this.packets = 0;
+ this.bytes = 0;
+ this.lastSeen = System.currentTimeMillis();
+ }
+
+ @Override
+ public long life() {
+ return life;
+ }
+
+ @Override
+ public long packets() {
+ return packets;
+ }
+
+ @Override
+ public long bytes() {
+ return bytes;
+ }
+
+ @Override
+ public FlowEntryState state() {
+ return this.state;
+ }
+
+ @Override
+ public long lastSeen() {
+ return lastSeen;
+ }
+
+ @Override
+ public void setLastSeen() {
+ this.lastSeen = System.currentTimeMillis();
+ }
+
+ @Override
+ public void setState(FlowEntryState newState) {
+ this.state = newState;
+ }
+
+ @Override
+ public void setLife(long life) {
+ this.life = life;
+ }
+
+ @Override
+ public void setPackets(long packets) {
+ this.packets = packets;
+ }
+
+ @Override
+ public void setBytes(long bytes) {
+ this.bytes = bytes;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("rule", super.toString())
+ .add("state", state)
+ .toString();
+ }
+
+
+}
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/DefaultFlowRule.java b/core/api/src/main/java/org/onlab/onos/net/flow/DefaultFlowRule.java
index 9b44fc2..9011a93 100644
--- a/core/api/src/main/java/org/onlab/onos/net/flow/DefaultFlowRule.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/DefaultFlowRule.java
@@ -18,10 +18,6 @@
private final TrafficSelector selector;
private final TrafficTreatment treatment;
private final long created;
- private final long life;
- private final long packets;
- private final long bytes;
- private final FlowRuleState state;
private final FlowId id;
@@ -29,90 +25,50 @@
private final int timeout;
- /**
- * Creates a flow rule given the following paremeters.
- * @param deviceId the device where the rule should be installed
- * @param selector the traffic selection
- * @param treatment how the seleted traffic should be handled
- * @param priority the rule priority cannot be less than FlowRule.MIN_PRIORITY
- * @param state the state in which the rule is
- * @param life how long it has existed for (ms)
- * @param packets number of packets it has seen
- * @param bytes number of bytes it has seen
- * @param flowId the identifier
- * @param timeout the rule's timeout (idle) not to exceed
- * FlowRule.MAX_TIMEOUT of idle time
- */
+
public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
- TrafficTreatment treatment, int priority, FlowRuleState state,
- long life, long packets, long bytes, long flowId,
+ TrafficTreatment treatment, int priority, long flowId,
int timeout) {
this.deviceId = deviceId;
this.priority = priority;
this.selector = selector;
this.treatment = treatment;
- this.state = state;
+ this.timeout = timeout;
+ this.created = System.currentTimeMillis();
+
this.appId = ApplicationId.valueOf((int) (flowId >> 32));
this.id = FlowId.valueOf(flowId);
- this.life = life;
- this.packets = packets;
- this.bytes = bytes;
- this.created = System.currentTimeMillis();
- this.timeout = timeout;
}
public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
TrafficTreatment treatement, int priority, ApplicationId appId,
int timeout) {
- this(deviceId, selector, treatement, priority,
- FlowRuleState.CREATED, appId, timeout);
- }
- public DefaultFlowRule(FlowRule rule, FlowRuleState state) {
- this(rule.deviceId(), rule.selector(), rule.treatment(),
- rule.priority(), state, rule.id(), rule.appId(),
- rule.timeout());
- }
-
- private DefaultFlowRule(DeviceId deviceId,
- TrafficSelector selector, TrafficTreatment treatment,
- int priority, FlowRuleState state, ApplicationId appId,
- int timeout) {
- if (priority < MIN_PRIORITY) {
+ if (priority < FlowRule.MIN_PRIORITY) {
throw new IllegalArgumentException("Priority cannot be less than " + MIN_PRIORITY);
}
+
this.deviceId = deviceId;
this.priority = priority;
this.selector = selector;
- this.treatment = treatment;
- this.state = state;
- this.life = 0;
- this.packets = 0;
- this.bytes = 0;
+ this.treatment = treatement;
this.appId = appId;
-
this.timeout = timeout;
+ this.created = System.currentTimeMillis();
this.id = FlowId.valueOf((((long) appId().id()) << 32) | (this.hash() & 0xffffffffL));
- this.created = System.currentTimeMillis();
}
- private DefaultFlowRule(DeviceId deviceId,
- TrafficSelector selector, TrafficTreatment treatment,
- int priority, FlowRuleState state, FlowId flowId, ApplicationId appId,
- int timeout) {
- this.deviceId = deviceId;
- this.priority = priority;
- this.selector = selector;
- this.treatment = treatment;
- this.state = state;
- this.life = 0;
- this.packets = 0;
- this.bytes = 0;
- this.appId = appId;
- this.id = flowId;
- this.timeout = timeout;
+ public DefaultFlowRule(FlowRule rule) {
+ this.deviceId = rule.deviceId();
+ this.priority = rule.priority();
+ this.selector = rule.selector();
+ this.treatment = rule.treatment();
+ this.appId = rule.appId();
+ this.id = rule.id();
+ this.timeout = rule.timeout();
this.created = System.currentTimeMillis();
+
}
@@ -146,26 +102,6 @@
return treatment;
}
- @Override
- public long life() {
- return life;
- }
-
- @Override
- public long packets() {
- return packets;
- }
-
- @Override
- public long bytes() {
- return bytes;
- }
-
- @Override
- public FlowRuleState state() {
- return this.state;
- }
-
@Override
/*
@@ -213,7 +149,6 @@
.add("selector", selector.criteria())
.add("treatment", treatment == null ? "N/A" : treatment.instructions())
.add("created", created)
- .add("state", state)
.toString();
}
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/FlowEntry.java b/core/api/src/main/java/org/onlab/onos/net/flow/FlowEntry.java
new file mode 100644
index 0000000..5b5f89b
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/FlowEntry.java
@@ -0,0 +1,98 @@
+package org.onlab.onos.net.flow;
+
+
+/**
+ * Represents a generalized match & action pair to be applied to
+ * an infrastucture device.
+ */
+public interface FlowEntry extends FlowRule {
+
+
+ public enum FlowEntryState {
+
+ /**
+ * Indicates that this rule has been submitted for addition.
+ * Not necessarily in the flow table.
+ */
+ PENDING_ADD,
+
+ /**
+ * Rule has been added which means it is in the flow table.
+ */
+ ADDED,
+
+ /**
+ * Flow has been marked for removal, might still be in flow table.
+ */
+ PENDING_REMOVE,
+
+ /**
+ * Flow has been removed from flow table and can be purged.
+ */
+ REMOVED
+ }
+
+ /**
+ * Returns the flow entry state.
+ *
+ * @return flow entry state
+ */
+ FlowEntryState state();
+
+ /**
+ * Returns the number of milliseconds this flow rule has been applied.
+ *
+ * @return number of millis
+ */
+ long life();
+
+ /**
+ * Returns the number of packets this flow rule has matched.
+ *
+ * @return number of packets
+ */
+ long packets();
+
+ /**
+ * Returns the number of bytes this flow rule has matched.
+ *
+ * @return number of bytes
+ */
+ long bytes();
+
+ /**
+ * When this flow entry was last deemed active.
+ * @return epoch time of last activity
+ */
+ long lastSeen();
+
+ /**
+ * Sets the last active epoch time.
+ */
+ void setLastSeen();
+
+ /**
+ * Sets the new state for this entry.
+ * @param newState new flow entry state.
+ */
+ void setState(FlowEntryState newState);
+
+ /**
+ * Sets how long this entry has been entered in the system.
+ * @param life epoch time
+ */
+ void setLife(long life);
+
+ /**
+ * Number of packets seen by this entry.
+ * @param packets a long value
+ */
+ void setPackets(long packets);
+
+ /**
+ * Number of bytes seen by this rule.
+ * @param bytes a long value
+ */
+ void setBytes(long bytes);
+
+}
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/FlowRule.java b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRule.java
index 9b76f32..8b30c74 100644
--- a/core/api/src/main/java/org/onlab/onos/net/flow/FlowRule.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRule.java
@@ -12,41 +12,6 @@
static final int MAX_TIMEOUT = 60;
static final int MIN_PRIORITY = 0;
- public enum FlowRuleState {
- /**
- * Indicates that this rule has been created.
- */
- CREATED,
-
- /**
- * Indicates that this rule has been submitted for addition.
- * Not necessarily in the flow table.
- */
- PENDING_ADD,
-
- /**
- * Rule has been added which means it is in the flow table.
- */
- ADDED,
-
- /**
- * Flow has been marked for removal, might still be in flow table.
- */
- PENDING_REMOVE,
-
- /**
- * Flow has been removed from flow table and can be purged.
- */
- REMOVED
- }
-
- /**
- * Returns the flow rule state.
- *
- * @return flow rule state
- */
- FlowRuleState state();
-
//TODO: build cookie value
/**
* Returns the ID of this flow.
@@ -93,27 +58,6 @@
TrafficTreatment treatment();
/**
- * Returns the number of milliseconds this flow rule has been applied.
- *
- * @return number of millis
- */
- long life();
-
- /**
- * Returns the number of packets this flow rule has matched.
- *
- * @return number of packets
- */
- long packets();
-
- /**
- * Returns the number of bytes this flow rule has matched.
- *
- * @return number of bytes
- */
- long bytes();
-
- /**
* Returns the timeout for this flow requested by an application.
* @return integer value of the timeout
*/
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleProviderService.java b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleProviderService.java
index 2076103..8164579 100644
--- a/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleProviderService.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleProviderService.java
@@ -14,7 +14,7 @@
*
* @param flowRule information about the removed flow
*/
- void flowRemoved(FlowRule flowRule);
+ void flowRemoved(FlowEntry flowEntry);
/**
* Pushes the collection of flow entries currently applied on the given
@@ -22,7 +22,7 @@
*
* @param flowRules collection of flow rules
*/
- void pushFlowMetrics(DeviceId deviceId, Iterable<FlowRule> flowRules);
+ void pushFlowMetrics(DeviceId deviceId, Iterable<FlowEntry> flowEntries);
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleService.java b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleService.java
index c09a56d..2ebc5a25 100644
--- a/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleService.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleService.java
@@ -20,7 +20,7 @@
* @param deviceId device identifier
* @return collection of flow rules
*/
- Iterable<FlowRule> getFlowEntries(DeviceId deviceId);
+ Iterable<FlowEntry> getFlowEntries(DeviceId deviceId);
// TODO: add createFlowRule factory method and execute operations method
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleStore.java b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleStore.java
index c6093384..4d68e74 100644
--- a/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleStore.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleStore.java
@@ -14,7 +14,7 @@
* @param rule the rule to look for
* @return a flow rule
*/
- FlowRule getFlowRule(FlowRule rule);
+ FlowEntry getFlowEntry(FlowRule rule);
/**
* Returns the flow entries associated with a device.
@@ -22,7 +22,7 @@
* @param deviceId the device ID
* @return the flow entries
*/
- Iterable<FlowRule> getFlowEntries(DeviceId deviceId);
+ Iterable<FlowEntry> getFlowEntries(DeviceId deviceId);
/**
* Returns the flow entries associated with an application.
@@ -30,7 +30,7 @@
* @param appId the application id
* @return the flow entries
*/
- Iterable<FlowRule> getFlowEntriesByAppId(ApplicationId appId);
+ Iterable<FlowRule> getFlowRulesByAppId(ApplicationId appId);
/**
* Stores a new flow rule without generating events.
@@ -40,7 +40,8 @@
void storeFlowRule(FlowRule rule);
/**
- * Deletes a flow rule without generating events.
+ * Marks a flow rule for deletion. Actual deletion will occur
+ * when the provider indicates that the flow has been removed.
*
* @param rule the flow rule to delete
*/
@@ -52,12 +53,12 @@
* @param rule the flow rule to add or update
* @return flow_added event, or null if just an update
*/
- FlowRuleEvent addOrUpdateFlowRule(FlowRule rule);
+ FlowRuleEvent addOrUpdateFlowRule(FlowEntry rule);
/**
- * @param rule the flow rule to remove
+ * @param rule the flow entry to remove
* @return flow_removed event, or null if nothing removed
*/
- FlowRuleEvent removeFlowRule(FlowRule rule);
+ FlowRuleEvent removeFlowRule(FlowEntry rule);
}
diff --git a/core/net/src/main/java/org/onlab/onos/net/flow/impl/FlowRuleManager.java b/core/net/src/main/java/org/onlab/onos/net/flow/impl/FlowRuleManager.java
index 182e210..385e300 100644
--- a/core/net/src/main/java/org/onlab/onos/net/flow/impl/FlowRuleManager.java
+++ b/core/net/src/main/java/org/onlab/onos/net/flow/impl/FlowRuleManager.java
@@ -5,8 +5,6 @@
import java.util.Iterator;
import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
@@ -20,6 +18,7 @@
import org.onlab.onos.net.Device;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.device.DeviceService;
+import org.onlab.onos.net.flow.FlowEntry;
import org.onlab.onos.net.flow.FlowRule;
import org.onlab.onos.net.flow.FlowRuleEvent;
import org.onlab.onos.net.flow.FlowRuleListener;
@@ -61,8 +60,6 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected DeviceService deviceService;
- private final Map<FlowRule, Long> idleTime = new ConcurrentHashMap<>();
-
@Activate
public void activate() {
store.setDelegate(delegate);
@@ -78,7 +75,7 @@
}
@Override
- public Iterable<FlowRule> getFlowEntries(DeviceId deviceId) {
+ public Iterable<FlowEntry> getFlowEntries(DeviceId deviceId) {
return store.getFlowEntries(deviceId);
}
@@ -88,7 +85,6 @@
FlowRule f = flowRules[i];
final Device device = deviceService.getDevice(f.deviceId());
final FlowRuleProvider frp = getProvider(device.providerId());
- idleTime.put(f, System.currentTimeMillis());
store.storeFlowRule(f);
frp.applyFlowRule(f);
}
@@ -103,7 +99,6 @@
f = flowRules[i];
device = deviceService.getDevice(f.deviceId());
frp = getProvider(device.providerId());
- idleTime.remove(f);
store.deleteFlowRule(f);
frp.removeFlowRule(f);
}
@@ -125,7 +120,7 @@
@Override
public Iterable<FlowRule> getFlowRulesById(ApplicationId id) {
- return store.getFlowEntriesByAppId(id);
+ return store.getFlowRulesByAppId(id);
}
@Override
@@ -153,15 +148,15 @@
}
@Override
- public void flowRemoved(FlowRule flowRule) {
- checkNotNull(flowRule, FLOW_RULE_NULL);
+ public void flowRemoved(FlowEntry flowEntry) {
+ checkNotNull(flowEntry, FLOW_RULE_NULL);
checkValidity();
- FlowRule stored = store.getFlowRule(flowRule);
+ FlowEntry stored = store.getFlowEntry(flowEntry);
if (stored == null) {
- log.info("Rule already evicted from store: {}", flowRule);
+ log.info("Rule already evicted from store: {}", flowEntry);
return;
}
- Device device = deviceService.getDevice(flowRule.deviceId());
+ Device device = deviceService.getDevice(flowEntry.deviceId());
FlowRuleProvider frp = getProvider(device.providerId());
FlowRuleEvent event = null;
switch (stored.state()) {
@@ -171,20 +166,20 @@
break;
case PENDING_REMOVE:
case REMOVED:
- event = store.removeFlowRule(flowRule);
+ event = store.removeFlowRule(stored);
break;
default:
break;
}
if (event != null) {
- log.debug("Flow {} removed", flowRule);
+ log.debug("Flow {} removed", flowEntry);
post(event);
}
}
- private void flowMissing(FlowRule flowRule) {
+ private void flowMissing(FlowEntry flowRule) {
checkNotNull(flowRule, FLOW_RULE_NULL);
checkValidity();
Device device = deviceService.getDevice(flowRule.deviceId());
@@ -220,36 +215,37 @@
}
- private void flowAdded(FlowRule flowRule) {
- checkNotNull(flowRule, FLOW_RULE_NULL);
+ private void flowAdded(FlowEntry flowEntry) {
+ checkNotNull(flowEntry, FLOW_RULE_NULL);
checkValidity();
- if (idleTime.containsKey(flowRule) &&
- checkRuleLiveness(flowRule, store.getFlowRule(flowRule))) {
+ if (checkRuleLiveness(flowEntry, store.getFlowEntry(flowEntry))) {
- FlowRuleEvent event = store.addOrUpdateFlowRule(flowRule);
+ FlowRuleEvent event = store.addOrUpdateFlowRule(flowEntry);
if (event == null) {
log.debug("No flow store event generated.");
} else {
- log.debug("Flow {} {}", flowRule, event.type());
+ log.debug("Flow {} {}", flowEntry, event.type());
post(event);
}
} else {
- removeFlowRules(flowRule);
+ removeFlowRules(flowEntry);
}
}
- private boolean checkRuleLiveness(FlowRule swRule, FlowRule storedRule) {
+ private boolean checkRuleLiveness(FlowEntry swRule, FlowEntry storedRule) {
+ if (storedRule == null) {
+ return false;
+ }
long timeout = storedRule.timeout() * 1000;
Long currentTime = System.currentTimeMillis();
if (storedRule.packets() != swRule.packets()) {
- idleTime.put(swRule, currentTime);
+ storedRule.setLastSeen();
return true;
}
- if ((currentTime - idleTime.get(swRule)) <= timeout) {
- idleTime.put(swRule, currentTime);
+ if ((currentTime - storedRule.lastSeen()) <= timeout) {
return true;
}
return false;
@@ -263,13 +259,13 @@
}
@Override
- public void pushFlowMetrics(DeviceId deviceId, Iterable<FlowRule> flowEntries) {
- List<FlowRule> storedRules = Lists.newLinkedList(store.getFlowEntries(deviceId));
+ public void pushFlowMetrics(DeviceId deviceId, Iterable<FlowEntry> flowEntries) {
+ List<FlowEntry> storedRules = Lists.newLinkedList(store.getFlowEntries(deviceId));
- Iterator<FlowRule> switchRulesIterator = flowEntries.iterator();
+ Iterator<FlowEntry> switchRulesIterator = flowEntries.iterator();
while (switchRulesIterator.hasNext()) {
- FlowRule rule = switchRulesIterator.next();
+ FlowEntry rule = switchRulesIterator.next();
if (storedRules.remove(rule)) {
// we both have the rule, let's update some info then.
flowAdded(rule);
@@ -278,7 +274,7 @@
extraneousFlow(rule);
}
}
- for (FlowRule rule : storedRules) {
+ for (FlowEntry rule : storedRules) {
// there are rules in the store that aren't on the switch
flowMissing(rule);
diff --git a/core/net/src/test/java/org/onlab/onos/net/flow/impl/FlowRuleManagerTest.java b/core/net/src/test/java/org/onlab/onos/net/flow/impl/FlowRuleManagerTest.java
index 8922fd9..7463671 100644
--- a/core/net/src/test/java/org/onlab/onos/net/flow/impl/FlowRuleManagerTest.java
+++ b/core/net/src/test/java/org/onlab/onos/net/flow/impl/FlowRuleManagerTest.java
@@ -27,9 +27,11 @@
import org.onlab.onos.net.PortNumber;
import org.onlab.onos.net.device.DeviceListener;
import org.onlab.onos.net.device.DeviceService;
+import org.onlab.onos.net.flow.DefaultFlowEntry;
import org.onlab.onos.net.flow.DefaultFlowRule;
+import org.onlab.onos.net.flow.FlowEntry;
+import org.onlab.onos.net.flow.FlowEntry.FlowEntryState;
import org.onlab.onos.net.flow.FlowRule;
-import org.onlab.onos.net.flow.FlowRule.FlowRuleState;
import org.onlab.onos.net.flow.FlowRuleEvent;
import org.onlab.onos.net.flow.FlowRuleListener;
import org.onlab.onos.net.flow.FlowRuleProvider;
@@ -103,9 +105,6 @@
return new DefaultFlowRule(DID, ts, tr, 10, appId, TIMEOUT);
}
- private FlowRule flowRule(FlowRule rule, FlowRuleState state) {
- return new DefaultFlowRule(rule, state);
- }
private FlowRule addFlowRule(int hval) {
FlowRule rule = flowRule(hval, hval);
@@ -143,24 +142,26 @@
FlowRule f1 = addFlowRule(1);
FlowRule f2 = addFlowRule(2);
+ FlowEntry fe1 = new DefaultFlowEntry(f1);
+ FlowEntry fe2 = new DefaultFlowEntry(f2);
assertEquals("2 rules should exist", 2, flowCount());
- providerService.pushFlowMetrics(DID, ImmutableList.of(f1, f2));
+ providerService.pushFlowMetrics(DID, ImmutableList.of(fe1, fe2));
validateEvents(RULE_ADDED, RULE_ADDED);
addFlowRule(1);
assertEquals("should still be 2 rules", 2, flowCount());
- providerService.pushFlowMetrics(DID, ImmutableList.of(f1));
+ providerService.pushFlowMetrics(DID, ImmutableList.of(fe1));
validateEvents(RULE_UPDATED);
}
//backing store is sensitive to the order of additions/removals
- private boolean validateState(FlowRuleState... state) {
- Iterable<FlowRule> rules = service.getFlowEntries(DID);
+ private boolean validateState(FlowEntryState... state) {
+ Iterable<FlowEntry> rules = service.getFlowEntries(DID);
int i = 0;
- for (FlowRule f : rules) {
+ for (FlowEntry f : rules) {
if (f.state() != state[i]) {
return false;
}
@@ -181,8 +182,8 @@
mgr.applyFlowRules(r1, r2, r3);
assertEquals("3 rules should exist", 3, flowCount());
assertTrue("Entries should be pending add.",
- validateState(FlowRuleState.PENDING_ADD, FlowRuleState.PENDING_ADD,
- FlowRuleState.PENDING_ADD));
+ validateState(FlowEntryState.PENDING_ADD, FlowEntryState.PENDING_ADD,
+ FlowEntryState.PENDING_ADD));
}
@Test
@@ -192,20 +193,21 @@
FlowRule f3 = addFlowRule(3);
assertEquals("3 rules should exist", 3, flowCount());
- providerService.pushFlowMetrics(DID, ImmutableList.of(f1, f2, f3));
+ FlowEntry fe1 = new DefaultFlowEntry(f1);
+ FlowEntry fe2 = new DefaultFlowEntry(f2);
+ FlowEntry fe3 = new DefaultFlowEntry(f3);
+ providerService.pushFlowMetrics(DID, ImmutableList.of(fe1, fe2, fe3));
validateEvents(RULE_ADDED, RULE_ADDED, RULE_ADDED);
- FlowRule rem1 = flowRule(f1, FlowRuleState.REMOVED);
- FlowRule rem2 = flowRule(f2, FlowRuleState.REMOVED);
- mgr.removeFlowRules(rem1, rem2);
+ mgr.removeFlowRules(f1, f2);
//removing from north, so no events generated
validateEvents();
assertEquals("3 rule should exist", 3, flowCount());
assertTrue("Entries should be pending remove.",
- validateState(FlowRuleState.CREATED, FlowRuleState.PENDING_REMOVE,
- FlowRuleState.PENDING_REMOVE));
+ validateState(FlowEntryState.PENDING_REMOVE, FlowEntryState.PENDING_REMOVE,
+ FlowEntryState.ADDED));
- mgr.removeFlowRules(rem1);
+ mgr.removeFlowRules(f1);
assertEquals("3 rule should still exist", 3, flowCount());
}
@@ -213,21 +215,24 @@
public void flowRemoved() {
FlowRule f1 = addFlowRule(1);
FlowRule f2 = addFlowRule(2);
- providerService.pushFlowMetrics(f1.deviceId(), ImmutableList.of(f1, f2));
+ FlowEntry fe1 = new DefaultFlowEntry(f1);
+ FlowEntry fe2 = new DefaultFlowEntry(f2);
+ providerService.pushFlowMetrics(DID, ImmutableList.of(fe1, fe2));
service.removeFlowRules(f1);
- FlowRule rem1 = flowRule(f1, FlowRuleState.REMOVED);
- providerService.flowRemoved(rem1);
+ fe1.setState(FlowEntryState.REMOVED);
+ providerService.flowRemoved(fe1);
validateEvents(RULE_ADDED, RULE_ADDED, RULE_REMOVED);
- providerService.flowRemoved(rem1);
+ providerService.flowRemoved(fe1);
validateEvents();
FlowRule f3 = flowRule(3, 3);
+ FlowEntry fe3 = new DefaultFlowEntry(f3);
service.applyFlowRules(f3);
- providerService.pushFlowMetrics(f3.deviceId(), Collections.singletonList(f3));
+ providerService.pushFlowMetrics(DID, Collections.singletonList(fe3));
validateEvents(RULE_ADDED);
- providerService.flowRemoved(f3);
+ providerService.flowRemoved(fe3);
validateEvents();
}
@@ -237,17 +242,20 @@
FlowRule f2 = flowRule(2, 2);
FlowRule f3 = flowRule(3, 3);
-
-
mgr.applyFlowRules(f1, f2, f3);
- FlowRule updatedF1 = flowRule(f1, FlowRuleState.ADDED);
- FlowRule updatedF2 = flowRule(f2, FlowRuleState.ADDED);
- providerService.pushFlowMetrics(DID, Lists.newArrayList(updatedF1, updatedF2));
+ FlowEntry fe1 = new DefaultFlowEntry(f1);
+ FlowEntry fe2 = new DefaultFlowEntry(f2);
+
+
+ //FlowRule updatedF1 = flowRule(f1, FlowRuleState.ADDED);
+ //FlowRule updatedF2 = flowRule(f2, FlowRuleState.ADDED);
+
+ providerService.pushFlowMetrics(DID, Lists.newArrayList(fe1, fe2));
assertTrue("Entries should be added.",
- validateState(FlowRuleState.PENDING_ADD, FlowRuleState.ADDED,
- FlowRuleState.ADDED));
+ validateState(FlowEntryState.ADDED, FlowEntryState.ADDED,
+ FlowEntryState.PENDING_ADD));
validateEvents(RULE_ADDED, RULE_ADDED);
}
@@ -259,11 +267,15 @@
FlowRule f3 = flowRule(3, 3);
mgr.applyFlowRules(f1, f2);
- FlowRule updatedF1 = flowRule(f1, FlowRuleState.ADDED);
- FlowRule updatedF2 = flowRule(f2, FlowRuleState.ADDED);
- FlowRule updatedF3 = flowRule(f3, FlowRuleState.ADDED);
+// FlowRule updatedF1 = flowRule(f1, FlowRuleState.ADDED);
+// FlowRule updatedF2 = flowRule(f2, FlowRuleState.ADDED);
+// FlowRule updatedF3 = flowRule(f3, FlowRuleState.ADDED);
+ FlowEntry fe1 = new DefaultFlowEntry(f1);
+ FlowEntry fe2 = new DefaultFlowEntry(f2);
+ FlowEntry fe3 = new DefaultFlowEntry(f3);
- providerService.pushFlowMetrics(DID, Lists.newArrayList(updatedF1, updatedF2, updatedF3));
+
+ providerService.pushFlowMetrics(DID, Lists.newArrayList(fe1, fe2, fe3));
validateEvents(RULE_ADDED, RULE_ADDED);
@@ -279,13 +291,16 @@
FlowRule f2 = flowRule(2, 2);
FlowRule f3 = flowRule(3, 3);
- FlowRule updatedF1 = flowRule(f1, FlowRuleState.ADDED);
- FlowRule updatedF2 = flowRule(f2, FlowRuleState.ADDED);
+// FlowRule updatedF1 = flowRule(f1, FlowRuleState.ADDED);
+// FlowRule updatedF2 = flowRule(f2, FlowRuleState.ADDED);
+
+ FlowEntry fe1 = new DefaultFlowEntry(f1);
+ FlowEntry fe2 = new DefaultFlowEntry(f2);
mgr.applyFlowRules(f1, f2, f3);
mgr.removeFlowRules(f3);
- providerService.pushFlowMetrics(DID, Lists.newArrayList(updatedF1, updatedF2));
+ providerService.pushFlowMetrics(DID, Lists.newArrayList(fe1, fe2));
validateEvents(RULE_ADDED, RULE_ADDED, RULE_REMOVED);
@@ -312,7 +327,7 @@
//only check that we are in pending remove. Events and actual remove state will
// be set by flowRemoved call.
- validateState(FlowRuleState.PENDING_REMOVE, FlowRuleState.PENDING_REMOVE);
+ validateState(FlowEntryState.PENDING_REMOVE, FlowEntryState.PENDING_REMOVE);
}
private static class TestListener implements FlowRuleListener {
diff --git a/core/store/dist/src/main/java/org/onlab/onos/store/flow/impl/DistributedFlowRuleStore.java b/core/store/dist/src/main/java/org/onlab/onos/store/flow/impl/DistributedFlowRuleStore.java
index 5a5592a..f3c8f34 100644
--- a/core/store/dist/src/main/java/org/onlab/onos/store/flow/impl/DistributedFlowRuleStore.java
+++ b/core/store/dist/src/main/java/org/onlab/onos/store/flow/impl/DistributedFlowRuleStore.java
@@ -1,6 +1,5 @@
package org.onlab.onos.store.flow.impl;
-import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_ADDED;
import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_REMOVED;
import static org.slf4j.LoggerFactory.getLogger;
@@ -13,9 +12,10 @@
import org.apache.felix.scr.annotations.Service;
import org.onlab.onos.ApplicationId;
import org.onlab.onos.net.DeviceId;
-import org.onlab.onos.net.flow.DefaultFlowRule;
+import org.onlab.onos.net.flow.DefaultFlowEntry;
+import org.onlab.onos.net.flow.FlowEntry;
+import org.onlab.onos.net.flow.FlowEntry.FlowEntryState;
import org.onlab.onos.net.flow.FlowRule;
-import org.onlab.onos.net.flow.FlowRule.FlowRuleState;
import org.onlab.onos.net.flow.FlowRuleEvent;
import org.onlab.onos.net.flow.FlowRuleEvent.Type;
import org.onlab.onos.net.flow.FlowRuleStore;
@@ -30,18 +30,18 @@
/**
* Manages inventory of flow rules using trivial in-memory implementation.
*/
-//FIXME: I LIE I AM NOT DISTRIBUTED
+//FIXME I LIE. I AIN'T DISTRIBUTED
@Component(immediate = true)
@Service
public class DistributedFlowRuleStore
-extends AbstractStore<FlowRuleEvent, FlowRuleStoreDelegate>
-implements FlowRuleStore {
+ extends AbstractStore<FlowRuleEvent, FlowRuleStoreDelegate>
+ implements FlowRuleStore {
private final Logger log = getLogger(getClass());
// store entries as a pile of rules, no info about device tables
- private final Multimap<DeviceId, FlowRule> flowEntries =
- ArrayListMultimap.<DeviceId, FlowRule>create();
+ private final Multimap<DeviceId, FlowEntry> flowEntries =
+ ArrayListMultimap.<DeviceId, FlowEntry>create();
private final Multimap<ApplicationId, FlowRule> flowEntriesById =
ArrayListMultimap.<ApplicationId, FlowRule>create();
@@ -58,8 +58,8 @@
@Override
- public synchronized FlowRule getFlowRule(FlowRule rule) {
- for (FlowRule f : flowEntries.get(rule.deviceId())) {
+ public synchronized FlowEntry getFlowEntry(FlowRule rule) {
+ for (FlowEntry f : flowEntries.get(rule.deviceId())) {
if (f.equals(rule)) {
return f;
}
@@ -68,8 +68,8 @@
}
@Override
- public synchronized Iterable<FlowRule> getFlowEntries(DeviceId deviceId) {
- Collection<FlowRule> rules = flowEntries.get(deviceId);
+ public synchronized Iterable<FlowEntry> getFlowEntries(DeviceId deviceId) {
+ Collection<FlowEntry> rules = flowEntries.get(deviceId);
if (rules == null) {
return Collections.emptyList();
}
@@ -77,7 +77,7 @@
}
@Override
- public synchronized Iterable<FlowRule> getFlowEntriesByAppId(ApplicationId appId) {
+ public synchronized Iterable<FlowRule> getFlowRulesByAppId(ApplicationId appId) {
Collection<FlowRule> rules = flowEntriesById.get(appId);
if (rules == null) {
return Collections.emptyList();
@@ -87,7 +87,7 @@
@Override
public synchronized void storeFlowRule(FlowRule rule) {
- FlowRule f = new DefaultFlowRule(rule, FlowRuleState.PENDING_ADD);
+ FlowEntry f = new DefaultFlowEntry(rule);
DeviceId did = f.deviceId();
if (!flowEntries.containsEntry(did, f)) {
flowEntries.put(did, f);
@@ -97,57 +97,41 @@
@Override
public synchronized void deleteFlowRule(FlowRule rule) {
- FlowRule f = new DefaultFlowRule(rule, FlowRuleState.PENDING_REMOVE);
- DeviceId did = f.deviceId();
-
- /*
- * find the rule and mark it for deletion.
- * Ultimately a flow removed will come remove it.
- */
-
- if (flowEntries.containsEntry(did, f)) {
- //synchronized (flowEntries) {
- flowEntries.remove(did, f);
- flowEntries.put(did, f);
- flowEntriesById.remove(rule.appId(), rule);
- //}
+ FlowEntry entry = getFlowEntry(rule);
+ if (entry == null) {
+ return;
}
+ entry.setState(FlowEntryState.PENDING_REMOVE);
}
@Override
- public synchronized FlowRuleEvent addOrUpdateFlowRule(FlowRule rule) {
+ public synchronized FlowRuleEvent addOrUpdateFlowRule(FlowEntry rule) {
DeviceId did = rule.deviceId();
// check if this new rule is an update to an existing entry
- if (flowEntries.containsEntry(did, rule)) {
- //synchronized (flowEntries) {
- // Multimaps support duplicates so we have to remove our rule
- // and replace it with the current version.
- flowEntries.remove(did, rule);
- flowEntries.put(did, rule);
- //}
+ FlowEntry stored = getFlowEntry(rule);
+ if (stored != null) {
+ stored.setBytes(rule.bytes());
+ stored.setLife(rule.life());
+ stored.setPackets(rule.packets());
+ if (stored.state() == FlowEntryState.PENDING_ADD) {
+ stored.setState(FlowEntryState.ADDED);
+ return new FlowRuleEvent(Type.RULE_ADDED, rule);
+ }
return new FlowRuleEvent(Type.RULE_UPDATED, rule);
}
flowEntries.put(did, rule);
- return new FlowRuleEvent(RULE_ADDED, rule);
+ return null;
}
@Override
- public synchronized FlowRuleEvent removeFlowRule(FlowRule rule) {
- //synchronized (this) {
+ public synchronized FlowRuleEvent removeFlowRule(FlowEntry rule) {
+ // This is where one could mark a rule as removed and still keep it in the store.
if (flowEntries.remove(rule.deviceId(), rule)) {
return new FlowRuleEvent(RULE_REMOVED, rule);
} else {
return null;
}
- //}
}
-
-
-
-
-
-
-
}
diff --git a/core/store/hz/net/src/main/java/org/onlab/onos/store/flow/impl/DistributedFlowRuleStore.java b/core/store/hz/net/src/main/java/org/onlab/onos/store/flow/impl/DistributedFlowRuleStore.java
index 6ec7c51..f3c8f34 100644
--- a/core/store/hz/net/src/main/java/org/onlab/onos/store/flow/impl/DistributedFlowRuleStore.java
+++ b/core/store/hz/net/src/main/java/org/onlab/onos/store/flow/impl/DistributedFlowRuleStore.java
@@ -1,6 +1,5 @@
package org.onlab.onos.store.flow.impl;
-import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_ADDED;
import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_REMOVED;
import static org.slf4j.LoggerFactory.getLogger;
@@ -13,9 +12,10 @@
import org.apache.felix.scr.annotations.Service;
import org.onlab.onos.ApplicationId;
import org.onlab.onos.net.DeviceId;
-import org.onlab.onos.net.flow.DefaultFlowRule;
+import org.onlab.onos.net.flow.DefaultFlowEntry;
+import org.onlab.onos.net.flow.FlowEntry;
+import org.onlab.onos.net.flow.FlowEntry.FlowEntryState;
import org.onlab.onos.net.flow.FlowRule;
-import org.onlab.onos.net.flow.FlowRule.FlowRuleState;
import org.onlab.onos.net.flow.FlowRuleEvent;
import org.onlab.onos.net.flow.FlowRuleEvent.Type;
import org.onlab.onos.net.flow.FlowRuleStore;
@@ -28,20 +28,20 @@
import com.google.common.collect.Multimap;
/**
- * TEMPORARY: Manages inventory of flow rules using distributed store implementation.
+ * Manages inventory of flow rules using trivial in-memory implementation.
*/
-//FIXME: I LIE I AM NOT DISTRIBUTED
+//FIXME I LIE. I AIN'T DISTRIBUTED
@Component(immediate = true)
@Service
public class DistributedFlowRuleStore
-extends AbstractStore<FlowRuleEvent, FlowRuleStoreDelegate>
-implements FlowRuleStore {
+ extends AbstractStore<FlowRuleEvent, FlowRuleStoreDelegate>
+ implements FlowRuleStore {
private final Logger log = getLogger(getClass());
// store entries as a pile of rules, no info about device tables
- private final Multimap<DeviceId, FlowRule> flowEntries =
- ArrayListMultimap.<DeviceId, FlowRule>create();
+ private final Multimap<DeviceId, FlowEntry> flowEntries =
+ ArrayListMultimap.<DeviceId, FlowEntry>create();
private final Multimap<ApplicationId, FlowRule> flowEntriesById =
ArrayListMultimap.<ApplicationId, FlowRule>create();
@@ -58,8 +58,8 @@
@Override
- public synchronized FlowRule getFlowRule(FlowRule rule) {
- for (FlowRule f : flowEntries.get(rule.deviceId())) {
+ public synchronized FlowEntry getFlowEntry(FlowRule rule) {
+ for (FlowEntry f : flowEntries.get(rule.deviceId())) {
if (f.equals(rule)) {
return f;
}
@@ -68,8 +68,8 @@
}
@Override
- public synchronized Iterable<FlowRule> getFlowEntries(DeviceId deviceId) {
- Collection<FlowRule> rules = flowEntries.get(deviceId);
+ public synchronized Iterable<FlowEntry> getFlowEntries(DeviceId deviceId) {
+ Collection<FlowEntry> rules = flowEntries.get(deviceId);
if (rules == null) {
return Collections.emptyList();
}
@@ -77,7 +77,7 @@
}
@Override
- public synchronized Iterable<FlowRule> getFlowEntriesByAppId(ApplicationId appId) {
+ public synchronized Iterable<FlowRule> getFlowRulesByAppId(ApplicationId appId) {
Collection<FlowRule> rules = flowEntriesById.get(appId);
if (rules == null) {
return Collections.emptyList();
@@ -87,7 +87,7 @@
@Override
public synchronized void storeFlowRule(FlowRule rule) {
- FlowRule f = new DefaultFlowRule(rule, FlowRuleState.PENDING_ADD);
+ FlowEntry f = new DefaultFlowEntry(rule);
DeviceId did = f.deviceId();
if (!flowEntries.containsEntry(did, f)) {
flowEntries.put(did, f);
@@ -97,57 +97,41 @@
@Override
public synchronized void deleteFlowRule(FlowRule rule) {
- FlowRule f = new DefaultFlowRule(rule, FlowRuleState.PENDING_REMOVE);
- DeviceId did = f.deviceId();
-
- /*
- * find the rule and mark it for deletion.
- * Ultimately a flow removed will come remove it.
- */
-
- if (flowEntries.containsEntry(did, f)) {
- //synchronized (flowEntries) {
- flowEntries.remove(did, f);
- flowEntries.put(did, f);
- flowEntriesById.remove(rule.appId(), rule);
- //}
+ FlowEntry entry = getFlowEntry(rule);
+ if (entry == null) {
+ return;
}
+ entry.setState(FlowEntryState.PENDING_REMOVE);
}
@Override
- public synchronized FlowRuleEvent addOrUpdateFlowRule(FlowRule rule) {
+ public synchronized FlowRuleEvent addOrUpdateFlowRule(FlowEntry rule) {
DeviceId did = rule.deviceId();
// check if this new rule is an update to an existing entry
- if (flowEntries.containsEntry(did, rule)) {
- //synchronized (flowEntries) {
- // Multimaps support duplicates so we have to remove our rule
- // and replace it with the current version.
- flowEntries.remove(did, rule);
- flowEntries.put(did, rule);
- //}
+ FlowEntry stored = getFlowEntry(rule);
+ if (stored != null) {
+ stored.setBytes(rule.bytes());
+ stored.setLife(rule.life());
+ stored.setPackets(rule.packets());
+ if (stored.state() == FlowEntryState.PENDING_ADD) {
+ stored.setState(FlowEntryState.ADDED);
+ return new FlowRuleEvent(Type.RULE_ADDED, rule);
+ }
return new FlowRuleEvent(Type.RULE_UPDATED, rule);
}
flowEntries.put(did, rule);
- return new FlowRuleEvent(RULE_ADDED, rule);
+ return null;
}
@Override
- public synchronized FlowRuleEvent removeFlowRule(FlowRule rule) {
- //synchronized (this) {
+ public synchronized FlowRuleEvent removeFlowRule(FlowEntry rule) {
+ // This is where one could mark a rule as removed and still keep it in the store.
if (flowEntries.remove(rule.deviceId(), rule)) {
return new FlowRuleEvent(RULE_REMOVED, rule);
} else {
return null;
}
- //}
}
-
-
-
-
-
-
-
}
diff --git a/core/store/trivial/src/main/java/org/onlab/onos/store/trivial/impl/SimpleFlowRuleStore.java b/core/store/trivial/src/main/java/org/onlab/onos/store/trivial/impl/SimpleFlowRuleStore.java
index d12d00e..5fa92f3 100644
--- a/core/store/trivial/src/main/java/org/onlab/onos/store/trivial/impl/SimpleFlowRuleStore.java
+++ b/core/store/trivial/src/main/java/org/onlab/onos/store/trivial/impl/SimpleFlowRuleStore.java
@@ -12,9 +12,10 @@
import org.apache.felix.scr.annotations.Service;
import org.onlab.onos.ApplicationId;
import org.onlab.onos.net.DeviceId;
-import org.onlab.onos.net.flow.DefaultFlowRule;
+import org.onlab.onos.net.flow.DefaultFlowEntry;
+import org.onlab.onos.net.flow.FlowEntry;
+import org.onlab.onos.net.flow.FlowEntry.FlowEntryState;
import org.onlab.onos.net.flow.FlowRule;
-import org.onlab.onos.net.flow.FlowRule.FlowRuleState;
import org.onlab.onos.net.flow.FlowRuleEvent;
import org.onlab.onos.net.flow.FlowRuleEvent.Type;
import org.onlab.onos.net.flow.FlowRuleStore;
@@ -38,8 +39,8 @@
private final Logger log = getLogger(getClass());
// store entries as a pile of rules, no info about device tables
- private final Multimap<DeviceId, FlowRule> flowEntries =
- ArrayListMultimap.<DeviceId, FlowRule>create();
+ private final Multimap<DeviceId, FlowEntry> flowEntries =
+ ArrayListMultimap.<DeviceId, FlowEntry>create();
private final Multimap<ApplicationId, FlowRule> flowEntriesById =
ArrayListMultimap.<ApplicationId, FlowRule>create();
@@ -56,8 +57,8 @@
@Override
- public synchronized FlowRule getFlowRule(FlowRule rule) {
- for (FlowRule f : flowEntries.get(rule.deviceId())) {
+ public synchronized FlowEntry getFlowEntry(FlowRule rule) {
+ for (FlowEntry f : flowEntries.get(rule.deviceId())) {
if (f.equals(rule)) {
return f;
}
@@ -66,8 +67,8 @@
}
@Override
- public synchronized Iterable<FlowRule> getFlowEntries(DeviceId deviceId) {
- Collection<FlowRule> rules = flowEntries.get(deviceId);
+ public synchronized Iterable<FlowEntry> getFlowEntries(DeviceId deviceId) {
+ Collection<FlowEntry> rules = flowEntries.get(deviceId);
if (rules == null) {
return Collections.emptyList();
}
@@ -75,7 +76,7 @@
}
@Override
- public synchronized Iterable<FlowRule> getFlowEntriesByAppId(ApplicationId appId) {
+ public synchronized Iterable<FlowRule> getFlowRulesByAppId(ApplicationId appId) {
Collection<FlowRule> rules = flowEntriesById.get(appId);
if (rules == null) {
return Collections.emptyList();
@@ -85,7 +86,7 @@
@Override
public synchronized void storeFlowRule(FlowRule rule) {
- FlowRule f = new DefaultFlowRule(rule, FlowRuleState.PENDING_ADD);
+ FlowEntry f = new DefaultFlowEntry(rule);
DeviceId did = f.deviceId();
if (!flowEntries.containsEntry(did, f)) {
flowEntries.put(did, f);
@@ -95,34 +96,25 @@
@Override
public synchronized void deleteFlowRule(FlowRule rule) {
- FlowRule f = new DefaultFlowRule(rule, FlowRuleState.PENDING_REMOVE);
- DeviceId did = f.deviceId();
-
- /*
- * find the rule and mark it for deletion.
- * Ultimately a flow removed will come remove it.
- */
-
- if (flowEntries.containsEntry(did, f)) {
- flowEntries.remove(did, f);
- flowEntries.put(did, f);
- flowEntriesById.remove(rule.appId(), rule);
+ FlowEntry entry = getFlowEntry(rule);
+ if (entry == null) {
+ return;
}
+ entry.setState(FlowEntryState.PENDING_REMOVE);
}
@Override
- public synchronized FlowRuleEvent addOrUpdateFlowRule(FlowRule rule) {
+ public synchronized FlowRuleEvent addOrUpdateFlowRule(FlowEntry rule) {
DeviceId did = rule.deviceId();
// check if this new rule is an update to an existing entry
- FlowRule stored = getFlowRule(rule);
+ FlowEntry stored = getFlowEntry(rule);
if (stored != null) {
- // Multimaps support duplicates so we have to remove our rule
- // and replace it with the current version.
- flowEntries.remove(did, rule);
- flowEntries.put(did, rule);
-
- if (stored.state() == FlowRuleState.PENDING_ADD) {
+ stored.setBytes(rule.bytes());
+ stored.setLife(rule.life());
+ stored.setPackets(rule.packets());
+ if (stored.state() == FlowEntryState.PENDING_ADD) {
+ stored.setState(FlowEntryState.ADDED);
return new FlowRuleEvent(Type.RULE_ADDED, rule);
}
return new FlowRuleEvent(Type.RULE_UPDATED, rule);
@@ -133,13 +125,12 @@
}
@Override
- public synchronized FlowRuleEvent removeFlowRule(FlowRule rule) {
- //synchronized (this) {
+ public synchronized FlowRuleEvent removeFlowRule(FlowEntry rule) {
+ // This is where one could mark a rule as removed and still keep it in the store.
if (flowEntries.remove(rule.deviceId(), rule)) {
return new FlowRuleEvent(RULE_REMOVED, rule);
} else {
return null;
}
- //}
}
}
diff --git a/providers/openflow/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/FlowRuleBuilder.java b/providers/openflow/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/FlowEntryBuilder.java
similarity index 91%
rename from providers/openflow/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/FlowRuleBuilder.java
rename to providers/openflow/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/FlowEntryBuilder.java
index 028e857..14c2c22 100644
--- a/providers/openflow/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/FlowRuleBuilder.java
+++ b/providers/openflow/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/FlowEntryBuilder.java
@@ -6,11 +6,13 @@
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.PortNumber;
+import org.onlab.onos.net.flow.DefaultFlowEntry;
import org.onlab.onos.net.flow.DefaultFlowRule;
import org.onlab.onos.net.flow.DefaultTrafficSelector;
import org.onlab.onos.net.flow.DefaultTrafficTreatment;
+import org.onlab.onos.net.flow.FlowEntry;
+import org.onlab.onos.net.flow.FlowEntry.FlowEntryState;
import org.onlab.onos.net.flow.FlowRule;
-import org.onlab.onos.net.flow.FlowRule.FlowRuleState;
import org.onlab.onos.net.flow.TrafficSelector;
import org.onlab.onos.net.flow.TrafficTreatment;
import org.onlab.onos.openflow.controller.Dpid;
@@ -37,7 +39,7 @@
import com.google.common.collect.Lists;
-public class FlowRuleBuilder {
+public class FlowEntryBuilder {
private final Logger log = getLogger(getClass());
private final OFFlowStatsEntry stat;
@@ -51,7 +53,7 @@
private final boolean addedRule;
- public FlowRuleBuilder(Dpid dpid, OFFlowStatsEntry entry) {
+ public FlowEntryBuilder(Dpid dpid, OFFlowStatsEntry entry) {
this.stat = entry;
this.match = entry.getMatch();
this.actions = getActions(entry);
@@ -60,7 +62,7 @@
this.addedRule = true;
}
- public FlowRuleBuilder(Dpid dpid, OFFlowRemoved removed) {
+ public FlowEntryBuilder(Dpid dpid, OFFlowRemoved removed) {
this.match = removed.getMatch();
this.removed = removed;
@@ -71,20 +73,21 @@
}
- public FlowRule build() {
+ public FlowEntry build() {
if (addedRule) {
- return new DefaultFlowRule(DeviceId.deviceId(Dpid.uri(dpid)),
+ FlowRule rule = new DefaultFlowRule(DeviceId.deviceId(Dpid.uri(dpid)),
buildSelector(), buildTreatment(), stat.getPriority(),
- FlowRuleState.ADDED, stat.getDurationSec(),
- stat.getPacketCount().getValue(), stat.getByteCount().getValue(),
stat.getCookie().getValue(), stat.getIdleTimeout());
+ return new DefaultFlowEntry(rule, FlowEntryState.ADDED,
+ stat.getDurationSec(), stat.getPacketCount().getValue(),
+ stat.getByteCount().getValue());
+
} else {
- // TODO: revisit potentially.
- return new DefaultFlowRule(DeviceId.deviceId(Dpid.uri(dpid)),
+ FlowRule rule = new DefaultFlowRule(DeviceId.deviceId(Dpid.uri(dpid)),
buildSelector(), null, removed.getPriority(),
- FlowRuleState.REMOVED, removed.getDurationSec(),
- removed.getPacketCount().getValue(), removed.getByteCount().getValue(),
- removed.getCookie().getValue(), removed.getIdleTimeout());
+ removed.getCookie().getValue(), removed.getIdleTimeout());
+ return new DefaultFlowEntry(rule, FlowEntryState.REMOVED, removed.getDurationSec(),
+ removed.getPacketCount().getValue(), removed.getByteCount().getValue());
}
}
diff --git a/providers/openflow/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/OpenFlowRuleProvider.java b/providers/openflow/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/OpenFlowRuleProvider.java
index c4507b4..eac3c18 100644
--- a/providers/openflow/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/OpenFlowRuleProvider.java
+++ b/providers/openflow/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/OpenFlowRuleProvider.java
@@ -12,6 +12,7 @@
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.onlab.onos.ApplicationId;
import org.onlab.onos.net.DeviceId;
+import org.onlab.onos.net.flow.FlowEntry;
import org.onlab.onos.net.flow.FlowRule;
import org.onlab.onos.net.flow.FlowRuleProvider;
import org.onlab.onos.net.flow.FlowRuleProviderRegistry;
@@ -131,7 +132,7 @@
implements OpenFlowSwitchListener, OpenFlowEventListener {
private final Map<Dpid, FlowStatsCollector> collectors = Maps.newHashMap();
- private final Multimap<DeviceId, FlowRule> completeEntries =
+ private final Multimap<DeviceId, FlowEntry> completeEntries =
ArrayListMultimap.create();
@Override
@@ -158,7 +159,7 @@
//TODO: make this better
OFFlowRemoved removed = (OFFlowRemoved) msg;
- FlowRule fr = new FlowRuleBuilder(dpid, removed).build();
+ FlowEntry fr = new FlowEntryBuilder(dpid, removed).build();
providerService.flowRemoved(fr);
break;
case STATS_REPLY:
@@ -188,7 +189,7 @@
for (OFFlowStatsEntry reply : replies.getEntries()) {
if (!tableMissRule(dpid, reply)) {
- completeEntries.put(did, new FlowRuleBuilder(dpid, reply).build());
+ completeEntries.put(did, new FlowEntryBuilder(dpid, reply).build());
}
}