alshabib

trying to fix flow state

Change-Id: I62845842c66cb99cb14bd54bc9602edf7c0cae39
......@@ -2,6 +2,9 @@
<command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
<command>
<action class="org.onlab.onos.cli.net.FlowsListCommand"/>
</command>
<command>
<action class="org.onlab.onos.cli.net.DevicesListCommand"/>
</command>
<command>
......
......@@ -15,19 +15,20 @@ public class DefaultFlowRule implements FlowRule {
private final FlowId id;
private final long created;
private final long life;
private final long idle;
private final long packets;
private final long bytes;
private final FlowRuleState state;
public DefaultFlowRule(DeviceId deviceId,
TrafficSelector selector, TrafficTreatment treatment, int priority) {
TrafficSelector selector, TrafficTreatment treatment,
int priority, FlowRuleState state) {
this.deviceId = deviceId;
this.priority = priority;
this.selector = selector;
this.treatment = treatment;
this.state = state;
this.life = 0;
this.idle = 0;
this.packets = 0;
this.bytes = 0;
this.id = FlowId.valueOf(this.hashCode());
......@@ -35,22 +36,32 @@ public class DefaultFlowRule implements FlowRule {
}
public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
TrafficTreatment treatment, int priority,
long life, long idle, long packets, long bytes, Integer flowId) {
TrafficTreatment treatment, int priority, FlowRuleState state,
long life, long packets, long bytes, Integer flowId) {
this.deviceId = deviceId;
this.priority = priority;
this.selector = selector;
this.treatment = treatment;
this.state = state;
this.id = FlowId.valueOf(flowId);
this.life = life;
this.idle = idle;
this.packets = packets;
this.bytes = bytes;
this.created = System.currentTimeMillis();
}
public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
TrafficTreatment treatement, int priority) {
this(deviceId, selector, treatement, priority, FlowRuleState.CREATED);
}
public DefaultFlowRule(FlowRule rule, FlowRuleState state) {
this(rule.deviceId(), rule.selector(), rule.treatment(),
rule.priority(), state);
}
@Override
public FlowId id() {
......@@ -83,11 +94,6 @@ public class DefaultFlowRule implements FlowRule {
}
@Override
public long idleMillis() {
return idle;
}
@Override
public long packets() {
return packets;
}
......@@ -98,6 +104,12 @@ public class DefaultFlowRule implements FlowRule {
}
@Override
public FlowRuleState state() {
return this.state;
}
@Override
/*
* The priority and statistics can change on a given treatment and selector
*
......@@ -116,19 +128,14 @@ public class DefaultFlowRule implements FlowRule {
* @see java.lang.Object#equals(java.lang.Object)
*/
public boolean equals(Object obj) {
if (obj instanceof FlowRule) {
DefaultFlowRule that = (DefaultFlowRule) obj;
if (!this.deviceId().equals(that.deviceId())) {
return false;
}
if (!this.treatment().equals(that.treatment())) {
return false;
}
if (!this.selector().equals(that.selector())) {
return false;
}
if (this == obj) {
return true;
}
if (obj instanceof FlowRule) {
FlowRule that = (FlowRule) obj;
return Objects.equals(deviceId, that.deviceId()) &&
Objects.equals(id, that.id());
}
return false;
}
......@@ -144,5 +151,4 @@ public class DefaultFlowRule implements FlowRule {
.toString();
}
}
......
package org.onlab.onos.net.flow;
import com.google.common.base.Objects;
/**
* Representation of a Flow ID.
*/
public final class FlowId {
private final int flowid;
private final long flowid;
private FlowId(int id) {
private FlowId(long id) {
this.flowid = id;
}
......@@ -15,7 +17,24 @@ public final class FlowId {
return new FlowId(id);
}
public int value() {
public long value() {
return flowid;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj.getClass() == this.getClass()) {
FlowId that = (FlowId) obj;
return Objects.equal(this.flowid, that.flowid);
}
return false;
}
@Override
public int hashCode() {
return Objects.hashCode(this.flowid);
}
}
......
......@@ -8,6 +8,42 @@ import org.onlab.onos.net.DeviceId;
*/
public interface FlowRule {
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.
......@@ -54,13 +90,6 @@ public interface FlowRule {
long lifeMillis();
/**
* Returns the number of milliseconds this flow rule has been idle.
*
* @return number of millis
*/
long idleMillis();
/**
* Returns the number of packets this flow rule has matched.
*
* @return number of packets
......
package org.onlab.onos.net.flow;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.provider.ProviderService;
/**
......@@ -35,6 +36,6 @@ public interface FlowRuleProviderService extends ProviderService<FlowRuleProvide
*
* @param flowRules collection of flow rules
*/
void pushFlowMetrics(Iterable<FlowRule> flowRules);
void pushFlowMetrics(DeviceId deviceId, Iterable<FlowRule> flowRules);
}
......
......@@ -4,6 +4,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import static org.slf4j.LoggerFactory.getLogger;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.felix.scr.annotations.Activate;
......@@ -17,7 +18,9 @@ import org.onlab.onos.event.EventDeliveryService;
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.DefaultFlowRule;
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;
......@@ -29,17 +32,19 @@ import org.onlab.onos.net.provider.AbstractProviderRegistry;
import org.onlab.onos.net.provider.AbstractProviderService;
import org.slf4j.Logger;
import com.google.common.collect.Lists;
@Component(immediate = true)
@Service
public class FlowRuleManager
extends AbstractProviderRegistry<FlowRuleProvider, FlowRuleProviderService>
implements FlowRuleService, FlowRuleProviderRegistry {
extends AbstractProviderRegistry<FlowRuleProvider, FlowRuleProviderService>
implements FlowRuleService, FlowRuleProviderRegistry {
public static final String FLOW_RULE_NULL = "FlowRule cannot be null";
private final Logger log = getLogger(getClass());
private final AbstractListenerRegistry<FlowRuleEvent, FlowRuleListener>
listenerRegistry = new AbstractListenerRegistry<>();
listenerRegistry = new AbstractListenerRegistry<>();
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected FlowRuleStore store;
......@@ -72,7 +77,7 @@ public class FlowRuleManager
List<FlowRule> entries = new ArrayList<FlowRule>();
for (int i = 0; i < flowRules.length; i++) {
FlowRule f = flowRules[i];
FlowRule f = new DefaultFlowRule(flowRules[i], FlowRuleState.PENDING_ADD);
final Device device = deviceService.getDevice(f.deviceId());
final FlowRuleProvider frp = getProvider(device.providerId());
entries.add(store.storeFlowRule(f));
......@@ -85,7 +90,7 @@ public class FlowRuleManager
@Override
public void removeFlowRules(FlowRule... flowRules) {
for (int i = 0; i < flowRules.length; i++) {
FlowRule f = flowRules[i];
FlowRule f = new DefaultFlowRule(flowRules[i], FlowRuleState.PENDING_REMOVE);
final Device device = deviceService.getDevice(f.deviceId());
final FlowRuleProvider frp = getProvider(device.providerId());
store.removeFlowRule(f);
......@@ -111,8 +116,8 @@ public class FlowRuleManager
}
private class InternalFlowRuleProviderService
extends AbstractProviderService<FlowRuleProvider>
implements FlowRuleProviderService {
extends AbstractProviderService<FlowRuleProvider>
implements FlowRuleProviderService {
protected InternalFlowRuleProviderService(FlowRuleProvider provider) {
super(provider);
......@@ -160,8 +165,32 @@ public class FlowRuleManager
}
@Override
public void pushFlowMetrics(Iterable<FlowRule> flowEntries) {
// TODO Auto-generated method stub
public void pushFlowMetrics(DeviceId deviceId, Iterable<FlowRule> flowEntries) {
List<FlowRule> storedRules = Lists.newLinkedList(store.getFlowEntries(deviceId));
List<FlowRule> switchRules = Lists.newLinkedList(flowEntries);
Iterator<FlowRule> switchRulesIterator = switchRules.iterator();
List<FlowRule> extraRules = Lists.newLinkedList();
while (switchRulesIterator.hasNext()) {
FlowRule rule = switchRulesIterator.next();
if (storedRules.remove(rule)) {
// we both have the rule let's update some info then.
log.info("rule {} is added. {}", rule.id(), rule.state());
flowAdded(rule);
} else {
// the device a rule the store does not have
extraRules.add(rule);
}
}
for (FlowRule rule : storedRules) {
// there are rules in the store that aren't on the switch
flowMissing(rule);
}
if (extraRules.size() > 0) {
log.warn("Device {} has extra flow rules: {}", deviceId, extraRules);
// TODO do something with this.
}
}
}
......
......@@ -10,6 +10,7 @@ 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.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.net.flow.criteria.Criteria;
......@@ -69,14 +70,14 @@ public class FlowRuleBuilder {
if (stat != null) {
return new DefaultFlowRule(DeviceId.deviceId(Dpid.uri(dpid)),
buildSelector(), buildTreatment(), stat.getPriority(),
stat.getDurationNsec() / 1000000, stat.getIdleTimeout(),
FlowRuleState.ADDED, stat.getDurationNsec() / 1000000,
stat.getPacketCount().getValue(), stat.getByteCount().getValue(),
(int) (stat.getCookie().getValue() & 0xFFFFFFFF));
} else {
// TODO: revisit potentially.
return new DefaultFlowRule(DeviceId.deviceId(Dpid.uri(dpid)),
buildSelector(), null, removed.getPriority(),
removed.getDurationNsec() / 1000000, removed.getIdleTimeout(),
FlowRuleState.REMOVED, removed.getDurationNsec() / 1000000,
removed.getPacketCount().getValue(), removed.getByteCount().getValue(),
(int) (removed.getCookie().getValue() & 0xFFFFFFFF));
}
......
......@@ -10,6 +10,7 @@ import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.flow.FlowRule;
import org.onlab.onos.net.flow.FlowRuleProvider;
import org.onlab.onos.net.flow.FlowRuleProviderRegistry;
......@@ -154,7 +155,7 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr
entries.add(new FlowRuleBuilder(dpid, reply).build());
}
log.debug("sending flowstats to core {}", entries);
providerService.pushFlowMetrics(entries);
providerService.pushFlowMetrics(DeviceId.deviceId(Dpid.uri(dpid)), entries);
}
}
......