[ONOS-5599] Recover OF multi part meter features stats message as part of handshake.
Change-Id: I047f1c9b1512b136cc441c8d0822ba2552f2d92e
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