[ONOS-4209] Unsuccessful PCEP session formation between ONOS and IOS XR
Change-Id: Ic509c50c5cef39e5f1a5319570f8c9406177b788
diff --git a/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepChannelHandler.java b/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepChannelHandler.java
index cf768ff..dd5d5f5 100644
--- a/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepChannelHandler.java
+++ b/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepChannelHandler.java
@@ -38,6 +38,7 @@
import org.jboss.netty.handler.timeout.IdleStateHandler;
import org.jboss.netty.handler.timeout.ReadTimeoutException;
import org.onlab.packet.IpAddress;
+import org.onosproject.pcep.controller.ClientCapability;
import org.onosproject.pcep.controller.PccId;
import org.onosproject.pcep.controller.driver.PcepClientDriver;
import org.onosproject.pcepio.exceptions.PcepParseException;
@@ -51,7 +52,6 @@
import org.onosproject.pcepio.protocol.PcepOpenObject;
import org.onosproject.pcepio.protocol.PcepType;
import org.onosproject.pcepio.protocol.PcepVersion;
-import org.onosproject.pcepio.types.ErrorObjListWithOpen;
import org.onosproject.pcepio.types.PceccCapabilityTlv;
import org.onosproject.pcepio.types.StatefulPceCapabilityTlv;
import org.onosproject.pcepio.types.PcepErrorDetailInfo;
@@ -74,6 +74,7 @@
private byte sessionId = 0;
private byte keepAliveTime;
private byte deadTime;
+ private ClientCapability capability;
private PcepPacketStatsImpl pcepPacketStats;
static final int MAX_WRONG_COUNT_PACKET = 5;
static final int BYTE_MASK = 0xFF;
@@ -146,8 +147,8 @@
h.pcepPacketStats.addInPacket();
PcepOpenMsg pOpenmsg = (PcepOpenMsg) m;
- // do Capability validation.
- if (h.capabilityValidation(pOpenmsg)) {
+ //Do Capability negotiation.
+ h.capabilityNegotiation(pOpenmsg);
log.debug("Sending handshake OPEN message");
h.sessionId = pOpenmsg.getPcepOpenObject().getSessionId();
h.pcepVersion = pOpenmsg.getPcepOpenObject().getVersion();
@@ -168,13 +169,6 @@
h.sendHandshakeOpenMessage();
h.pcepPacketStats.addOutPacket();
h.setState(KEEPWAIT);
- } else {
- log.debug("Capability validation failed. Sending PCEP-ERROR message to PCC.");
- // Send PCEP-ERROR message.
- PcepErrorMsg errMsg = h.getErrorMsg(PcepErrorDetailInfo.ERROR_TYPE_2,
- PcepErrorDetailInfo.ERROR_VALUE_2);
- h.channel.write(Collections.singletonList(errMsg));
- }
}
}
},
@@ -203,6 +197,8 @@
h.thispccId = PccId.pccId(IpAddress.valueOf(inetAddress.getAddress()));
h.pc = h.controller.getPcepClientInstance(h.thispccId, h.sessionId, h.pcepVersion,
h.pcepPacketStats);
+ //Get pc instance and set capabilities
+ h.pc.setCapability(h.capability);
// set the status of pcc as connected
h.pc.setConnected(true);
h.pc.setChannel(h.channel);
@@ -493,17 +489,12 @@
channel.write(Collections.singletonList(msg));
}
- /**
- * Capability Validation.
- *
- * @param pOpenmsg pcep open message
- * @return success or failure
- */
- private boolean capabilityValidation(PcepOpenMsg pOpenmsg) {
+ //Capability negotiation
+ private void capabilityNegotiation(PcepOpenMsg pOpenmsg) {
LinkedList<PcepValueType> tlvList = pOpenmsg.getPcepOpenObject().getOptionalTlv();
- boolean bFoundPceccCapability = false;
- boolean bFoundStatefulPceCapability = false;
- boolean bFoundPcInstantiationCapability = false;
+ boolean pceccCapability = false;
+ boolean statefulPceCapability = false;
+ boolean pcInstantiationCapability = false;
ListIterator<PcepValueType> listIterator = tlvList.listIterator();
while (listIterator.hasNext()) {
@@ -511,21 +502,20 @@
switch (tlv.getType()) {
case PceccCapabilityTlv.TYPE:
- bFoundPceccCapability = true;
+ pceccCapability = true;
break;
case StatefulPceCapabilityTlv.TYPE:
- bFoundStatefulPceCapability = true;
+ statefulPceCapability = true;
StatefulPceCapabilityTlv stetefulPcCapTlv = (StatefulPceCapabilityTlv) tlv;
if (stetefulPcCapTlv.getIFlag()) {
- bFoundPcInstantiationCapability = true;
+ pcInstantiationCapability = true;
}
break;
default:
continue;
}
}
-
- return (bFoundPceccCapability && bFoundStatefulPceCapability && bFoundPcInstantiationCapability);
+ this.capability = new ClientCapability(pceccCapability, statefulPceCapability, pcInstantiationCapability);
}
/**
@@ -579,23 +569,6 @@
llerrObj.add(errObj);
- if (state == ChannelState.OPENWAIT) {
- //If Error caught in Openmessage
- PcepOpenObject openObj = null;
- ErrorObjListWithOpen errorObjListWithOpen = null;
-
- if (0 != sessionId) {
- openObj = factory1.buildOpenObject().setSessionId(sessionId).build();
- errorObjListWithOpen = new ErrorObjListWithOpen(llerrObj, openObj);
- } else {
- errorObjListWithOpen = new ErrorObjListWithOpen(llerrObj, null);
- }
-
- errMsg = factory1.buildPcepErrorMsg()
- .setErrorObjListWithOpen(errorObjListWithOpen)
- .build();
- } else {
-
//If Error caught in other than Openmessage
LinkedList<PcepError> llPcepErr = new LinkedList<>();
@@ -612,7 +585,6 @@
errMsg = factory1.buildPcepErrorMsg()
.setPcepErrorInfo(errInfo)
.build();
- }
return errMsg;
}
diff --git a/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepClientControllerImpl.java b/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepClientControllerImpl.java
index d15e285..1f58bed 100644
--- a/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepClientControllerImpl.java
+++ b/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepClientControllerImpl.java
@@ -18,6 +18,7 @@
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
+import java.util.LinkedList;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@@ -31,12 +32,20 @@
import org.onosproject.pcep.controller.PcepClientListener;
import org.onosproject.pcep.controller.PcepEventListener;
import org.onosproject.pcep.controller.driver.PcepAgent;
+import org.onosproject.pcepio.protocol.PcepError;
+import org.onosproject.pcepio.protocol.PcepErrorInfo;
+import org.onosproject.pcepio.protocol.PcepErrorMsg;
+import org.onosproject.pcepio.protocol.PcepErrorObject;
+import org.onosproject.pcepio.protocol.PcepFactory;
import org.onosproject.pcepio.protocol.PcepMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.Sets;
+import static org.onosproject.pcepio.types.PcepErrorDetailInfo.ERROR_TYPE_19;
+import static org.onosproject.pcepio.types.PcepErrorDetailInfo.ERROR_VALUE_5;
+
/**
* Implementation of PCEP client controller.
*/
@@ -126,6 +135,24 @@
break;
case ERROR:
break;
+ case INITIATE:
+ if (!pc.capability().pcInstantiationCapability()) {
+ pc.sendMessage(Collections.singletonList(getErrMsg(pc.factory(), ERROR_TYPE_19,
+ ERROR_VALUE_5)));
+ }
+ break;
+ case UPDATE:
+ if (!pc.capability().statefulPceCapability()) {
+ pc.sendMessage(Collections.singletonList(getErrMsg(pc.factory(), ERROR_TYPE_19,
+ ERROR_VALUE_5)));
+ }
+ break;
+ case LABEL_UPDATE:
+ if (!pc.capability().pceccCapability()) {
+ pc.sendMessage(Collections.singletonList(getErrMsg(pc.factory(), ERROR_TYPE_19,
+ ERROR_VALUE_5)));
+ }
+ break;
case CLOSE:
log.info("Sending Close Message to {" + pccId.toString() + "}");
pc.sendMessage(Collections.singletonList(pc.factory().buildCloseMsg().build()));
@@ -133,21 +160,18 @@
pc.disconnectClient();
break;
case REPORT:
- for (PcepEventListener l : pcepEventListener) {
- l.handleMessage(pccId, msg);
+ //Only update the listener if respective capability is supported else send PCEP-ERR msg
+ if (pc.capability().statefulPceCapability()) {
+ for (PcepEventListener l : pcepEventListener) {
+ l.handleMessage(pccId, msg);
+ }
+ } else {
+ // Send PCEP-ERROR message.
+ pc.sendMessage(Collections.singletonList(getErrMsg(pc.factory(),
+ ERROR_TYPE_19, ERROR_VALUE_5)));
}
break;
- case UPDATE:
- for (PcepEventListener l : pcepEventListener) {
- l.handleMessage(pccId, msg);
- }
- break;
- case INITIATE:
- for (PcepEventListener l : pcepEventListener) {
- l.handleMessage(pccId, msg);
- }
- break;
- case LABEL_UPDATE:
+ case LABEL_RANGE_RESERV:
break;
case MAX:
break;
@@ -168,6 +192,34 @@
}
/**
+ * Returns pcep error message with specific error type and value.
+ *
+ * @param factory represents pcep factory
+ * @param errorType pcep error type
+ * @param errorValue pcep error value
+ * @return pcep error message
+ */
+ public PcepErrorMsg getErrMsg(PcepFactory factory, byte errorType, byte errorValue) {
+ LinkedList<PcepError> llPcepErr = new LinkedList<>();
+
+ LinkedList<PcepErrorObject> llerrObj = new LinkedList<>();
+ PcepErrorMsg errMsg;
+
+ PcepErrorObject errObj = factory.buildPcepErrorObject().setErrorValue(errorValue).setErrorType(errorType)
+ .build();
+
+ llerrObj.add(errObj);
+ PcepError pcepErr = factory.buildPcepError().setErrorObjList(llerrObj).build();
+
+ llPcepErr.add(pcepErr);
+
+ PcepErrorInfo errInfo = factory.buildPcepErrorInfo().setPcepErrorList(llPcepErr).build();
+
+ errMsg = factory.buildPcepErrorMsg().setPcepErrorInfo(errInfo).build();
+ return errMsg;
+ }
+
+ /**
* Implementation of an Pcep Agent which is responsible for
* keeping track of connected clients and the state in which
* they are.
diff --git a/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepClientImpl.java b/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepClientImpl.java
index 8c807f6..23b6ba6 100644
--- a/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepClientImpl.java
+++ b/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepClientImpl.java
@@ -24,6 +24,7 @@
import org.jboss.netty.channel.Channel;
import org.onlab.packet.IpAddress;
+import org.onosproject.pcep.controller.ClientCapability;
import org.onosproject.pcep.controller.PccId;
import org.onosproject.pcep.controller.PcepPacketStats;
import org.onosproject.pcep.controller.driver.PcepAgent;
@@ -57,6 +58,7 @@
private PccId pccId;
private PcepAgent agent;
+ private ClientCapability capability;
private PcepVersion pcepVersion;
private byte keepAliveTime;
private byte deadTime;
@@ -76,6 +78,16 @@
}
@Override
+ public void setCapability(ClientCapability capability) {
+ this.capability = capability;
+ }
+
+ @Override
+ public ClientCapability capability() {
+ return capability;
+ }
+
+ @Override
public final void sendMessage(PcepMessage m) {
log.debug("Sending message to {}", channel.getRemoteAddress());
try {