stats reported
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 564416c..fae1fe3 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
@@ -2,6 +2,8 @@
import static com.google.common.base.MoreObjects.toStringHelper;
+import java.util.Objects;
+
import org.onlab.onos.net.DeviceId;
public class DefaultFlowRule implements FlowRule {
@@ -12,10 +14,10 @@
private final TrafficTreatment treatment;
private final FlowId id;
private final long created;
- private long life;
- private long idle;
- private long packets;
- private long bytes;
+ private final long life;
+ private final long idle;
+ private final long packets;
+ private final long bytes;
public DefaultFlowRule(DeviceId deviceId,
@@ -32,15 +34,21 @@
this.created = System.currentTimeMillis();
}
- // TODO: Decide whether to take the flowId from the underlying flowentry.
public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
TrafficTreatment treatment, int priority,
- long life, long idle, long packets, long bytes) {
- this(deviceId, selector, treatment, priority);
+ long life, long idle, long packets, long bytes, Integer flowId) {
+ this.deviceId = deviceId;
+ this.priority = priority;
+ this.selector = selector;
+ this.treatment = treatment;
+
+ this.id = FlowId.valueOf(flowId);
+
this.life = life;
this.idle = idle;
this.packets = packets;
this.bytes = bytes;
+ this.created = System.currentTimeMillis();
}
@@ -97,11 +105,7 @@
* @see java.lang.Object#equals(java.lang.Object)
*/
public int hashCode() {
- final int prime = 31;
- int result = prime * this.deviceId().hashCode();
- result = prime * result + selector.hashCode();
- result = prime * result + treatment.hashCode();
- return result;
+ return Objects.hash(deviceId, selector, treatment);
}
@Override
@@ -140,4 +144,5 @@
.toString();
}
+
}
diff --git a/providers/openflow/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/FlowModBuilder.java b/providers/openflow/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/FlowModBuilder.java
index ecdd17c..b2e7cf4 100644
--- a/providers/openflow/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/FlowModBuilder.java
+++ b/providers/openflow/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/FlowModBuilder.java
@@ -6,6 +6,7 @@
import java.util.LinkedList;
import java.util.List;
+import org.onlab.onos.net.flow.FlowId;
import org.onlab.onos.net.flow.FlowRule;
import org.onlab.onos.net.flow.TrafficSelector;
import org.onlab.onos.net.flow.TrafficTreatment;
@@ -39,6 +40,7 @@
import org.projectfloodlight.openflow.types.OFBufferId;
import org.projectfloodlight.openflow.types.OFPort;
import org.projectfloodlight.openflow.types.OFVlanVidMatch;
+import org.projectfloodlight.openflow.types.U64;
import org.projectfloodlight.openflow.types.VlanPcp;
import org.projectfloodlight.openflow.types.VlanVid;
import org.slf4j.Logger;
@@ -54,6 +56,8 @@
private final int priority;
+ private final FlowId cookie;
+
public FlowModBuilder(FlowRule flowRule, OFFactory factory) {
@@ -61,6 +65,7 @@
this.treatment = flowRule.treatment();
this.selector = flowRule.selector();
this.priority = flowRule.priority();
+ this.cookie = flowRule.id();
}
public OFFlowMod buildFlowMod() {
@@ -69,6 +74,7 @@
//TODO: what to do without bufferid? do we assume that there will be a pktout as well?
OFFlowMod fm = factory.buildFlowModify()
+ .setCookie(U64.of(cookie.value()))
.setBufferId(OFBufferId.NO_BUFFER)
.setActions(actions)
.setMatch(match)
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/FlowRuleBuilder.java
new file mode 100644
index 0000000..33b6205
--- /dev/null
+++ b/providers/openflow/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/FlowRuleBuilder.java
@@ -0,0 +1,260 @@
+package org.onlab.onos.provider.of.flow.impl;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.util.List;
+
+import org.onlab.onos.net.DeviceId;
+import org.onlab.onos.net.PortNumber;
+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.TrafficSelector;
+import org.onlab.onos.net.flow.TrafficTreatment;
+import org.onlab.onos.net.flow.criteria.Criteria;
+import org.onlab.onos.net.flow.instructions.Instructions;
+import org.onlab.onos.openflow.controller.Dpid;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.projectfloodlight.openflow.protocol.OFFlowRemoved;
+import org.projectfloodlight.openflow.protocol.OFFlowStatsEntry;
+import org.projectfloodlight.openflow.protocol.action.OFAction;
+import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
+import org.projectfloodlight.openflow.protocol.action.OFActionSetDlDst;
+import org.projectfloodlight.openflow.protocol.action.OFActionSetDlSrc;
+import org.projectfloodlight.openflow.protocol.action.OFActionSetNwDst;
+import org.projectfloodlight.openflow.protocol.action.OFActionSetNwSrc;
+import org.projectfloodlight.openflow.protocol.action.OFActionSetVlanPcp;
+import org.projectfloodlight.openflow.protocol.action.OFActionSetVlanVid;
+import org.projectfloodlight.openflow.protocol.match.Match;
+import org.projectfloodlight.openflow.protocol.match.MatchField;
+import org.projectfloodlight.openflow.types.IPv4Address;
+import org.slf4j.Logger;
+
+public class FlowRuleBuilder {
+ private final Logger log = getLogger(getClass());
+
+ private final OFFlowStatsEntry stat;
+ private final OFFlowRemoved removed;
+
+ private final Match match;
+ private final List<OFAction> actions;
+
+ private final Dpid dpid;
+
+
+
+
+ public FlowRuleBuilder(Dpid dpid, OFFlowStatsEntry entry) {
+ this.stat = entry;
+ this.match = entry.getMatch();
+ this.actions = entry.getActions();
+ this.dpid = dpid;
+ removed = null;
+ }
+
+ public FlowRuleBuilder(Dpid dpid, OFFlowRemoved removed) {
+ this.match = removed.getMatch();
+ this.removed = removed;
+
+ this.dpid = dpid;
+ this.actions = null;
+ this.stat = null;
+
+ }
+
+ public FlowRule build() {
+ if (stat != null) {
+ return new DefaultFlowRule(DeviceId.deviceId(Dpid.uri(dpid)),
+ buildSelector(), buildTreatment(), stat.getPriority(),
+ stat.getDurationNsec() / 1000000, stat.getIdleTimeout(),
+ 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(),
+ removed.getPacketCount().getValue(), removed.getByteCount().getValue(),
+ (int) (removed.getCookie().getValue() & 0xFFFFFFFF));
+ }
+ }
+
+
+ private TrafficTreatment buildTreatment() {
+ TrafficTreatment.Builder builder = new DefaultTrafficTreatment.Builder();
+ // If this is a drop rule
+ if (actions.size() == 0) {
+ builder.add(Instructions.createDrop());
+ return builder.build();
+ }
+ for (OFAction act : actions) {
+ switch (act.getType()) {
+ case OUTPUT:
+ OFActionOutput out = (OFActionOutput) act;
+ builder.add(Instructions.createOutput(
+ PortNumber.portNumber(out.getPort().getPortNumber())));
+ break;
+ case SET_VLAN_PCP:
+ OFActionSetVlanVid vlan = (OFActionSetVlanVid) act;
+ builder.add(Instructions.modVlanId(VlanId.vlanId(vlan.getVlanVid().getVlan())));
+ break;
+ case SET_VLAN_VID:
+ OFActionSetVlanPcp pcp = (OFActionSetVlanPcp) act;
+ builder.add(Instructions.modVlanId(VlanId.vlanId(pcp.getVlanPcp().getValue())));
+ break;
+ case SET_DL_DST:
+ OFActionSetDlDst dldst = (OFActionSetDlDst) act;
+ builder.add(Instructions.modL2Dst(
+ MacAddress.valueOf(dldst.getDlAddr().getLong())));
+ break;
+ case SET_DL_SRC:
+ OFActionSetDlSrc dlsrc = (OFActionSetDlSrc) act;
+ builder.add(Instructions.modL2Src(
+ MacAddress.valueOf(dlsrc.getDlAddr().getLong())));
+
+ break;
+ case SET_NW_DST:
+ OFActionSetNwDst nwdst = (OFActionSetNwDst) act;
+ IPv4Address di = nwdst.getNwAddr();
+ if (di.isCidrMask()) {
+ builder.add(Instructions.modL3Dst(IpAddress.valueOf(di.getInt(),
+ di.asCidrMaskLength())));
+ } else {
+ builder.add(Instructions.modL3Dst(IpAddress.valueOf(di.getInt())));
+ }
+ break;
+ case SET_NW_SRC:
+ OFActionSetNwSrc nwsrc = (OFActionSetNwSrc) act;
+ IPv4Address si = nwsrc.getNwAddr();
+ if (si.isCidrMask()) {
+ builder.add(Instructions.modL3Dst(IpAddress.valueOf(si.getInt(),
+ si.asCidrMaskLength())));
+ } else {
+ builder.add(Instructions.modL3Dst(IpAddress.valueOf(si.getInt())));
+ }
+ break;
+ case SET_TP_DST:
+ case SET_TP_SRC:
+ case POP_MPLS:
+ case POP_PBB:
+ case POP_VLAN:
+ case PUSH_MPLS:
+ case PUSH_PBB:
+ case PUSH_VLAN:
+ case SET_FIELD:
+ case SET_MPLS_LABEL:
+ case SET_MPLS_TC:
+ case SET_MPLS_TTL:
+ case SET_NW_ECN:
+ case SET_NW_TOS:
+ case SET_NW_TTL:
+ case SET_QUEUE:
+ case STRIP_VLAN:
+ case COPY_TTL_IN:
+ case COPY_TTL_OUT:
+ case DEC_MPLS_TTL:
+ case DEC_NW_TTL:
+ case ENQUEUE:
+ case EXPERIMENTER:
+ case GROUP:
+ default:
+ log.warn("Action type {} not yet implemented.", act.getType());
+ }
+ }
+
+ return builder.build();
+ }
+
+ private TrafficSelector buildSelector() {
+ TrafficSelector.Builder builder = new DefaultTrafficSelector.Builder();
+ for (MatchField<?> field : match.getMatchFields()) {
+ switch (field.id) {
+ case IN_PORT:
+ builder.add(Criteria.matchInPort(PortNumber
+ .portNumber(match.get(MatchField.IN_PORT).getPortNumber())));
+ break;
+ case ETH_SRC:
+ MacAddress sMac = MacAddress.valueOf(match.get(MatchField.ETH_SRC).getLong());
+ builder.add(Criteria.matchEthSrc(sMac));
+ break;
+ case ETH_DST:
+ MacAddress dMac = MacAddress.valueOf(match.get(MatchField.ETH_DST).getLong());
+ builder.add(Criteria.matchEthSrc(dMac));
+ break;
+ case ETH_TYPE:
+ int ethType = match.get(MatchField.ETH_TYPE).getValue();
+ builder.add(Criteria.matchEthType((short) ethType));
+ break;
+ case IPV4_DST:
+ IPv4Address di = match.get(MatchField.IPV4_DST);
+ IpAddress dip;
+ if (di.isCidrMask()) {
+ dip = IpAddress.valueOf(di.getInt(), di.asCidrMaskLength());
+ } else {
+ dip = IpAddress.valueOf(di.getInt());
+ }
+ builder.add(Criteria.matchIPDst(dip));
+ break;
+ case IPV4_SRC:
+ IPv4Address si = match.get(MatchField.IPV4_SRC);
+ IpAddress sip;
+ if (si.isCidrMask()) {
+ sip = IpAddress.valueOf(si.getInt(), si.asCidrMaskLength());
+ } else {
+ sip = IpAddress.valueOf(si.getInt());
+ }
+ builder.add(Criteria.matchIPSrc(sip));
+ break;
+ case IP_PROTO:
+ short proto = match.get(MatchField.IP_PROTO).getIpProtocolNumber();
+ builder.add(Criteria.matchIPProtocol((byte) proto));
+ break;
+ case VLAN_PCP:
+ byte vlanPcp = match.get(MatchField.VLAN_PCP).getValue();
+ builder.add(Criteria.matchVlanPcp(vlanPcp));
+ break;
+ case VLAN_VID:
+ VlanId vlanId = VlanId.vlanId(match.get(MatchField.VLAN_VID).getVlan());
+ builder.add(Criteria.matchVlanId(vlanId));
+ break;
+ case ARP_OP:
+ case ARP_SHA:
+ case ARP_SPA:
+ case ARP_THA:
+ case ARP_TPA:
+ case ICMPV4_CODE:
+ case ICMPV4_TYPE:
+ case ICMPV6_CODE:
+ case ICMPV6_TYPE:
+ case IN_PHY_PORT:
+ case IPV6_DST:
+ case IPV6_FLABEL:
+ case IPV6_ND_SLL:
+ case IPV6_ND_TARGET:
+ case IPV6_ND_TLL:
+ case IPV6_SRC:
+ case IP_DSCP:
+ case IP_ECN:
+ case METADATA:
+ case MPLS_LABEL:
+ case MPLS_TC:
+ case SCTP_DST:
+ case SCTP_SRC:
+ case TCP_DST:
+ case TCP_SRC:
+ case TUNNEL_ID:
+ case UDP_DST:
+ case UDP_SRC:
+ default:
+ log.warn("Match type {} not yet implemented.", field.id);
+
+
+ }
+ }
+ return builder.build();
+ }
+
+}
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 73e00bb..b11eb0c 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
@@ -10,8 +10,6 @@
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.DefaultFlowRule;
import org.onlab.onos.net.flow.FlowRule;
import org.onlab.onos.net.flow.FlowRuleProvider;
import org.onlab.onos.net.flow.FlowRuleProviderRegistry;
@@ -131,7 +129,8 @@
case FLOW_REMOVED:
//TODO: make this better
OFFlowRemoved removed = (OFFlowRemoved) msg;
- FlowRule fr = new DefaultFlowRule(DeviceId.deviceId(Dpid.uri(dpid)), null, null, 0);
+
+ FlowRule fr = new FlowRuleBuilder(dpid, removed).build();
providerService.flowRemoved(fr);
break;
case STATS_REPLY:
@@ -154,6 +153,7 @@
for (OFFlowStatsEntry reply : replies.getEntries()) {
entries.add(new FlowRuleBuilder(dpid, reply).build());
}
+ log.debug("sending flowstats to core {}", entries);
providerService.pushFlowMetrics(entries);
}
diff --git a/tools/build/conf/src/main/resources/onos/checkstyle.xml b/tools/build/conf/src/main/resources/onos/checkstyle.xml
index 842e818..06413aa 100644
--- a/tools/build/conf/src/main/resources/onos/checkstyle.xml
+++ b/tools/build/conf/src/main/resources/onos/checkstyle.xml
@@ -175,8 +175,10 @@
<property name="max" value="200"/>
</module>
- <module name="ParameterNumber"/>
-
+ <module name="ParameterNumber">
+ <property name="max" value="10"/>
+ <property name="tokens" value="CTOR_DEF"/>
+ </module>
<!-- Checks for whitespace -->
<!-- See http://checkstyle.sf.net/config_whitespace.html -->
<module name="EmptyForIteratorPad"/>
@@ -272,6 +274,7 @@
<!-- <module name="TodoComment"/> -->
<module name="UpperEll"/>
+
</module>
</module>