[ONOS-5599] Recover OF multi part meter features stats message as part of handshake.
Change-Id: I047f1c9b1512b136cc441c8d0822ba2552f2d92e
diff --git a/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/AbstractOpenFlowSwitch.java b/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/AbstractOpenFlowSwitch.java
index 465dd06..128863e 100644
--- a/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/AbstractOpenFlowSwitch.java
+++ b/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/AbstractOpenFlowSwitch.java
@@ -30,6 +30,7 @@
import org.projectfloodlight.openflow.protocol.OFFactory;
import org.projectfloodlight.openflow.protocol.OFFeaturesReply;
import org.projectfloodlight.openflow.protocol.OFMessage;
+import org.projectfloodlight.openflow.protocol.OFMeterFeaturesStatsReply;
import org.projectfloodlight.openflow.protocol.OFNiciraControllerRoleRequest;
import org.projectfloodlight.openflow.protocol.OFPortDesc;
import org.projectfloodlight.openflow.protocol.OFPortDescStatsReply;
@@ -82,6 +83,8 @@
protected OFFeaturesReply features;
protected OFDescStatsReply desc;
+ protected OFMeterFeaturesStatsReply meterfeatures;
+
// messagesPendingMastership is used as synchronization variable for
// all mastership related changes. In this block, mastership (including
// role update) will have either occurred or not.
@@ -242,6 +245,11 @@
}
@Override
+ public void setMeterFeaturesReply(OFMeterFeaturesStatsReply meterFeaturesReply) {
+ meterfeatures = meterFeaturesReply;
+ }
+
+ @Override
public abstract Boolean supportNxRole();
//************************
diff --git a/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/OpenFlowSwitchDriver.java b/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/OpenFlowSwitchDriver.java
index 9cc0291..fc38aeb 100644
--- a/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/OpenFlowSwitchDriver.java
+++ b/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/OpenFlowSwitchDriver.java
@@ -23,6 +23,7 @@
import org.projectfloodlight.openflow.protocol.OFErrorMsg;
import org.projectfloodlight.openflow.protocol.OFFeaturesReply;
import org.projectfloodlight.openflow.protocol.OFMessage;
+import org.projectfloodlight.openflow.protocol.OFMeterFeaturesStatsReply;
import org.projectfloodlight.openflow.protocol.OFPortDescStatsReply;
import org.projectfloodlight.openflow.protocol.OFVersion;
@@ -134,6 +135,12 @@
void setFeaturesReply(OFFeaturesReply featuresReply);
/**
+ * Sets the meter features reply for this switch.
+ * @param meterFeaturesReply the meter features to set.
+ */
+ void setMeterFeaturesReply(OFMeterFeaturesStatsReply meterFeaturesReply);
+
+ /**
* Sets the switch description.
* @param desc the descriptions
*/
diff --git a/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OFChannelHandler.java b/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OFChannelHandler.java
index 79eaa6b..930f5dd 100644
--- a/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OFChannelHandler.java
+++ b/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OFChannelHandler.java
@@ -56,6 +56,8 @@
import org.projectfloodlight.openflow.protocol.OFHello;
import org.projectfloodlight.openflow.protocol.OFHelloElem;
import org.projectfloodlight.openflow.protocol.OFMessage;
+import org.projectfloodlight.openflow.protocol.OFMeterFeaturesStatsReply;
+import org.projectfloodlight.openflow.protocol.OFMeterFeaturesStatsRequest;
import org.projectfloodlight.openflow.protocol.OFPacketIn;
import org.projectfloodlight.openflow.protocol.OFPortDescStatsReply;
import org.projectfloodlight.openflow.protocol.OFPortDescStatsRequest;
@@ -102,6 +104,7 @@
// Temporary storage for switch-features and port-description
private OFFeaturesReply featuresReply;
private List<OFPortDescStatsReply> portDescReplies;
+ private OFMeterFeaturesStatsReply meterFeaturesReply;
//private OFPortDescStatsReply portDescReply;
// a concurrent ArrayList to temporarily store port status messages
// before we are ready to deal with them
@@ -357,8 +360,16 @@
h.getSwitchInfoString(),
m.getMissSendLen());
}
- h.sendHandshakeDescriptionStatsRequest();
- h.setState(WAIT_DESCRIPTION_STAT_REPLY);
+
+ if (h.ofVersion == OFVersion.OF_13) {
+ // Meters were introduced in OpenFlow 1.3
+ h.sendMeterFeaturesRequest();
+ h.setState(WAIT_METER_FEATURES_REPLY);
+ }
+ else {
+ h.sendHandshakeDescriptionStatsRequest();
+ h.setState(WAIT_DESCRIPTION_STAT_REPLY);
+ }
}
@Override
@@ -432,6 +443,7 @@
h.sw.setFeaturesReply(h.featuresReply);
//h.sw.setPortDescReply(h.portDescReply);
h.sw.setPortDescReplies(h.portDescReplies);
+ h.sw.setMeterFeaturesReply(h.meterFeaturesReply);
h.sw.setConnected(true);
h.sw.setChannel(h.channel);
// boolean success = h.sw.connectSwitch();
@@ -557,6 +569,54 @@
},
+ /**
+ * We are expecting a OF Multi Part Meter Features Stats Reply.
+ * Notice that this information is only available for switches running
+ * OpenFlow 1.3
+ */
+ WAIT_METER_FEATURES_REPLY(true) {
+ @Override
+ void processOFError(OFChannelHandler h, OFErrorMsg m)
+ throws IOException {
+ // will never be called. We override processOFMessage
+ }
+
+ @Override
+ void processOFStatisticsReply(OFChannelHandler h,
+ OFStatsReply m)
+ throws IOException, SwitchStateException {
+ switch(m.getStatsType()) {
+ case METER_FEATURES:
+
+ log.debug("Received Meter Features");
+ OFMeterFeaturesStatsReply ofmfsr = (OFMeterFeaturesStatsReply)m;
+ log.info("Received meter features from {} with max meters: {}",
+ h.getSwitchInfoString(),
+ ofmfsr.getFeatures().getMaxMeter());
+ h.meterFeaturesReply = ofmfsr;
+ h.sendHandshakeDescriptionStatsRequest();
+ h.setState(WAIT_DESCRIPTION_STAT_REPLY);
+ break;
+ default:
+ log.error("Unexpected OF Multi Part stats reply");
+ illegalMessageReceived(h, m);
+ break;
+ }
+ }
+
+ @Override
+ void processOFFeaturesReply(OFChannelHandler h, OFFeaturesReply m)
+ throws IOException, SwitchStateException {
+ illegalMessageReceived(h, m);
+ }
+
+ @Override
+ void processOFPortStatus(OFChannelHandler h, OFPortStatus m)
+ throws IOException {
+ h.pendingPortStatusMsg.add(m);
+ }
+ },
+
/**
* This controller is in MASTER role for this switch. We enter this state
@@ -1307,6 +1367,20 @@
channel.write(Collections.singletonList(dreq));
}
+ /**
+ * send a meter features request
+ * @throws IOException
+ */
+ private void sendMeterFeaturesRequest() throws IOException {
+ // Get meter features including the MaxMeters value available for the device
+ OFFactory factory = (ofVersion == OFVersion.OF_13) ? factory13 : factory10;
+ OFMeterFeaturesStatsRequest mfreq = factory
+ .buildMeterFeaturesStatsRequest()
+ .setXid(handshakeTransactionIds--)
+ .build();
+ channel.write(Collections.singletonList(mfreq));
+ }
+
private void sendHandshakeOFPortDescRequest() throws IOException {
// Get port description for 1.3 switch
OFPortDescStatsRequest preq = factory13
diff --git a/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/OpenflowSwitchDriverAdapter.java b/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/OpenflowSwitchDriverAdapter.java
index 115c9ea..11c47e1 100644
--- a/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/OpenflowSwitchDriverAdapter.java
+++ b/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/OpenflowSwitchDriverAdapter.java
@@ -31,6 +31,7 @@
import org.projectfloodlight.openflow.protocol.OFFactory;
import org.projectfloodlight.openflow.protocol.OFFeaturesReply;
import org.projectfloodlight.openflow.protocol.OFMessage;
+import org.projectfloodlight.openflow.protocol.OFMeterFeaturesStatsReply;
import org.projectfloodlight.openflow.protocol.OFPortDesc;
import org.projectfloodlight.openflow.protocol.OFPortDescStatsReply;
import org.projectfloodlight.openflow.protocol.OFVersion;
@@ -120,6 +121,11 @@
}
@Override
+ public void setMeterFeaturesReply(OFMeterFeaturesStatsReply meterFeaturesReply) {
+
+ }
+
+ @Override
public void setSwitchDescription(OFDescStatsReply desc) {
}