[ONOS-4209] Unsuccessful PCEP session formation between ONOS and IOS XR
Change-Id: Ic509c50c5cef39e5f1a5319570f8c9406177b788
diff --git a/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/ClientCapability.java b/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/ClientCapability.java
new file mode 100644
index 0000000..e2b5092
--- /dev/null
+++ b/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/ClientCapability.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2016 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.pcep.controller;
+
+import java.util.Objects;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Representation of capabilities supported by client.
+ */
+public class ClientCapability {
+ private boolean pceccCapability;
+ private boolean statefulPceCapability;
+ private boolean pcInstantiationCapability;
+
+ /**
+ * Creates new instance of client capability.
+ *
+ * @param pceccCapability represents PCECC capability
+ * @param statefulPceCapability represents stateful PCE capability
+ * @param pcInstantiationCapability represents PC initiation capability
+ */
+ public ClientCapability(boolean pceccCapability, boolean statefulPceCapability, boolean pcInstantiationCapability) {
+ this.pceccCapability = pceccCapability;
+ this.statefulPceCapability = statefulPceCapability;
+ this.pcInstantiationCapability = pcInstantiationCapability;
+ }
+
+ /**
+ * Obtains PCECC capability.
+ *
+ * @return true if client supports PCECC capability otherwise false
+ */
+ public boolean pceccCapability() {
+ return pceccCapability;
+ }
+
+ /**
+ * Obtains stateful PCE capability.
+ *
+ * @return true if client supports stateful PCE capability otherwise false
+ */
+ public boolean statefulPceCapability() {
+ return statefulPceCapability;
+ }
+
+ /**
+ * Obtains PC initiation capability.
+ *
+ * @return true if client supports PC initiation capability otherwise false
+ */
+ public boolean pcInstantiationCapability() {
+ return pcInstantiationCapability;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(pceccCapability, statefulPceCapability, pcInstantiationCapability);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof ClientCapability) {
+ ClientCapability other = (ClientCapability) obj;
+ return Objects.equals(pceccCapability, other.pceccCapability)
+ && Objects.equals(statefulPceCapability, other.statefulPceCapability)
+ && Objects.equals(pcInstantiationCapability, other.pcInstantiationCapability);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .add("pceccCapability", pceccCapability)
+ .add("statefulPceCapability", statefulPceCapability)
+ .add("pcInstantiationCapability", pcInstantiationCapability)
+ .toString();
+ }
+}
\ No newline at end of file
diff --git a/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepClient.java b/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepClient.java
old mode 100755
new mode 100644
index 11e4a69..5e3996a
--- a/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepClient.java
+++ b/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepClient.java
@@ -107,4 +107,18 @@
* @return true/false if the synchronization is completed/not completed
*/
boolean isSyncComplete();
+
+ /**
+ * Sets capability negotiated during open message exchange.
+ *
+ * @param capability supported by client
+ */
+ void setCapability(ClientCapability capability);
+
+ /**
+ * Obtains capability supported by client.
+ *
+ * @return capability supported by client
+ */
+ ClientCapability capability();
}
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 {
diff --git a/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepErrorDetailInfo.java b/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepErrorDetailInfo.java
index 6fee5ba..1bf6ce8 100644
--- a/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepErrorDetailInfo.java
+++ b/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepErrorDetailInfo.java
@@ -57,6 +57,26 @@
10 Reception of an invalid object
Error-value=1: reception of an object with P flag not set although the P flag must be
set according to this specification.
+
+ Reference draft-ietf-pce-stateful-pce-11, section : 8.4
+ 19 Invalid Operation
+ Error-value=1: Attempted LSP Update Request for a non-
+ delegated LSP. The PCEP-ERROR Object
+ is followed by the LSP Object that
+ identifies the LSP.
+ Error-value=2: Attempted LSP Update Request if the
+ stateful PCE capability was not
+ advertised.
+ Error-value=3: Attempted LSP Update Request for an LSP
+ identified by an unknown PLSP-ID.
+ Error-value=4: A PCE indicates to a PCC that it has
+ exceeded the resource limit allocated
+ for its state, and thus it cannot
+ accept and process its LSP State Report
+ message.
+ Error-value=5: Attempted LSP State Report if active
+ stateful PCE capability was not
+ advertised.
*/
public static final byte ERROR_TYPE_1 = 1;
public static final byte ERROR_TYPE_2 = 2;
@@ -68,6 +88,7 @@
public static final byte ERROR_TYPE_8 = 8;
public static final byte ERROR_TYPE_9 = 9;
public static final byte ERROR_TYPE_10 = 10;
+ public static final byte ERROR_TYPE_19 = 19;
// Error Values
public static final byte ERROR_VALUE_1 = 1;
diff --git a/providers/pcep/tunnel/pom.xml b/providers/pcep/tunnel/pom.xml
index 6aff760..ac5c335 100644
--- a/providers/pcep/tunnel/pom.xml
+++ b/providers/pcep/tunnel/pom.xml
@@ -51,4 +51,4 @@
<scope>test</scope>
</dependency>
</dependencies>
-</project>
\ No newline at end of file
+</project>
diff --git a/providers/pcep/tunnel/src/main/java/org/onosproject/provider/pcep/tunnel/impl/PcepTunnelProvider.java b/providers/pcep/tunnel/src/main/java/org/onosproject/provider/pcep/tunnel/impl/PcepTunnelProvider.java
index f973d46..45ae339 100644
--- a/providers/pcep/tunnel/src/main/java/org/onosproject/provider/pcep/tunnel/impl/PcepTunnelProvider.java
+++ b/providers/pcep/tunnel/src/main/java/org/onosproject/provider/pcep/tunnel/impl/PcepTunnelProvider.java
@@ -234,7 +234,11 @@
+ ((IpTunnelEndPoint) tunnel.src()).ip().toString());
return;
}
- pcepSetupTunnel(tunnel, path, pc);
+
+ //If stateful and PC Initiation capability is not supported by client not sending Initiate msg
+ if (pc.capability().pcInstantiationCapability()) {
+ pcepSetupTunnel(tunnel, path, pc);
+ }
}
@Override
@@ -263,7 +267,10 @@
+ ((IpElementId) srcElement).ipAddress().toString());
return;
}
- pcepSetupTunnel(tunnel, path, pc);
+
+ if (pc.capability().pcInstantiationCapability()) {
+ pcepSetupTunnel(tunnel, path, pc);
+ }
}
@Override
@@ -287,7 +294,10 @@
+ ((IpTunnelEndPoint) tunnel.src()).ip().toString());
return;
}
- pcepReleaseTunnel(tunnel, pc);
+
+ if (pc.capability().pcInstantiationCapability()) {
+ pcepReleaseTunnel(tunnel, pc);
+ }
}
@Override
@@ -315,7 +325,10 @@
+ ((IpElementId) srcElement).ipAddress().toString());
return;
}
- pcepReleaseTunnel(tunnel, pc);
+
+ if (pc.capability().pcInstantiationCapability()) {
+ pcepReleaseTunnel(tunnel, pc);
+ }
}
@Override
@@ -338,7 +351,10 @@
+ ((IpTunnelEndPoint) tunnel.src()).ip().toString());
return;
}
- pcepUpdateTunnel(tunnel, path, pc);
+
+ if (pc.capability().statefulPceCapability()) {
+ pcepUpdateTunnel(tunnel, path, pc);
+ }
}
@Override
@@ -367,7 +383,10 @@
+ ((IpElementId) srcElement).ipAddress().toString());
return;
}
- pcepUpdateTunnel(tunnel, path, pc);
+
+ if (pc.capability().statefulPceCapability()) {
+ pcepUpdateTunnel(tunnel, path, pc);
+ }
}
@Override
diff --git a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepClientAdapter.java b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepClientAdapter.java
index 9afac7e..efb4d95 100644
--- a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepClientAdapter.java
+++ b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepClientAdapter.java
@@ -21,6 +21,7 @@
import java.util.concurrent.RejectedExecutionException;
import org.jboss.netty.channel.Channel;
+import org.onosproject.pcep.controller.ClientCapability;
import org.onosproject.pcep.controller.PccId;
import org.onosproject.pcep.controller.PcepClient;
import org.onosproject.pcepio.protocol.PcepFactories;
@@ -28,6 +29,9 @@
import org.onosproject.pcepio.protocol.PcepMessage;
import org.onosproject.pcepio.protocol.PcepVersion;
+/**
+ * Representation of PCEP client adapter.
+ */
public class PcepClientAdapter implements PcepClient {
private Channel channel;
@@ -35,9 +39,16 @@
private boolean connected;
private PccId pccId;
+ private ClientCapability capability;
private PcepVersion pcepVersion;
+ /**
+ * Initialize instance with specified parameters.
+ *
+ * @param pccId PCC id
+ * @param pcepVersion PCEP message version
+ */
public void init(PccId pccId, PcepVersion pcepVersion) {
this.pccId = pccId;
this.pcepVersion = pcepVersion;
@@ -104,4 +115,14 @@
@Override
public final void setIsSyncComplete(boolean value) {
}
+
+ @Override
+ public void setCapability(ClientCapability capability) {
+ this.capability = capability;
+ }
+
+ @Override
+ public ClientCapability capability() {
+ return capability;
+ }
}
diff --git a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepClientControllerAdapter.java b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepClientControllerAdapter.java
index 8b78d23..91a68fc 100644
--- a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepClientControllerAdapter.java
+++ b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepClientControllerAdapter.java
@@ -18,23 +18,36 @@
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;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Deactivate;
import org.onlab.packet.IpAddress;
+import org.onosproject.pcep.controller.ClientCapability;
import org.onosproject.pcep.controller.PccId;
import org.onosproject.pcep.controller.PcepClient;
import org.onosproject.pcep.controller.PcepClientController;
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.onosproject.pcepio.protocol.PcepVersion;
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;
+
+/**
+ * Representation of PCEP client controller adapter.
+ */
public class PcepClientControllerAdapter implements PcepClientController {
protected ConcurrentHashMap<PccId, PcepClient> connectedClients =
@@ -60,9 +73,14 @@
@Override
public PcepClient getClient(PccId pccId) {
- //return connectedClients.get(pccIpAddress);
PcepClientAdapter pc = new PcepClientAdapter();
- pc.init(PccId.pccId(IpAddress.valueOf(0xac000001)), PcepVersion.PCEP_1);
+ if (pccId.ipAddress().equals(IpAddress.valueOf(0xC010103))
+ || pccId.ipAddress().equals(IpAddress.valueOf(0xB6024E22))) {
+ pc.setCapability(new ClientCapability(true, false, false));
+ } else {
+ pc.setCapability(new ClientCapability(true, true, true));
+ }
+ pc.init(PccId.pccId(pccId.ipAddress()), PcepVersion.PCEP_1);
return pc;
}
@@ -119,22 +137,35 @@
//log.debug("Sending Close Message to { }", pccIpAddress.toString());
pc.sendMessage(Collections.singletonList(pc.factory().buildCloseMsg().build()));
break;
+ case INITIATE:
+ if (!pc.capability().pcInstantiationCapability()) {
+ pc.sendMessage(Collections.singletonList(getErrMsg(pc.factory(),
+ ERROR_TYPE_19, ERROR_VALUE_5)));
+ }
+ 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);
+ 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 MAX:
break;
@@ -154,6 +185,26 @@
}
}
+ private 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
@@ -200,5 +251,4 @@
processClientMessage(pccId, m);
}
}
-
}
diff --git a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepReleaseTunnelProviderTest.java b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepReleaseTunnelProviderTest.java
index 8bbb6e8..bc84599 100644
--- a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepReleaseTunnelProviderTest.java
+++ b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepReleaseTunnelProviderTest.java
@@ -15,6 +15,10 @@
*/
package org.onosproject.provider.pcep.tunnel.impl;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.nullValue;
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsNot.not;
import static org.onosproject.net.DefaultAnnotations.EMPTY;
import java.io.IOException;
@@ -22,6 +26,7 @@
import java.util.List;
import org.junit.After;
+import org.junit.Before;
import org.junit.Test;
import org.onlab.packet.IpAddress;
import org.onosproject.cfg.ComponentConfigAdapter;
@@ -41,19 +46,21 @@
import org.onosproject.net.provider.ProviderId;
import org.onosproject.pcepio.types.StatefulIPv4LspIdentidiersTlv;
-
+/**
+ * Test for PCEP release tunnel.
+ */
public class PcepReleaseTunnelProviderTest {
- static final String PROVIDER_ID = "org.onosproject.provider.tunnel.pcep";
- PcepTunnelProvider tunnelProvider = new PcepTunnelProvider();
+ public static final String PROVIDER_ID = "org.onosproject.provider.tunnel.pcep";
+ private PcepTunnelProvider tunnelProvider = new PcepTunnelProvider();
private final TunnelProviderRegistryAdapter registry = new TunnelProviderRegistryAdapter();
private final PcepClientControllerAdapter controller = new PcepClientControllerAdapter();
private final PcepControllerAdapter ctl = new PcepControllerAdapter();
private final PcepTunnelApiMapper pcepTunnelAPIMapper = new PcepTunnelApiMapper();
private final TunnelServiceAdapter tunnelService = new TunnelServiceAdapter();
- @Test
- public void testCasePcepReleaseTunnel() {
+ @Before
+ public void setUp() throws IOException {
tunnelProvider.tunnelProviderRegistry = registry;
tunnelProvider.pcepClientController = controller;
tunnelProvider.controller = ctl;
@@ -61,7 +68,13 @@
tunnelProvider.pcepTunnelApiMapper = pcepTunnelAPIMapper;
tunnelProvider.cfgService = new ComponentConfigAdapter();
tunnelProvider.activate();
+ }
+ /**
+ * Release tunnel with negotiated capability.
+ */
+ @Test
+ public void testCasePcepReleaseTunnel() {
Tunnel tunnel;
Path path;
List<Link> links = new ArrayList<Link>();
@@ -104,8 +117,58 @@
tunnelProvider.pcepTunnelApiMapper.handleCreateTunnelRequestQueue(1, pcepTunnelData);
tunnelProvider.releaseTunnel(tunnel);
+ assertThat(tunnelProvider.pcepTunnelApiMapper, not(nullValue()));
}
+ /**
+ * Doesn't send initiate message because PCC doesn't supports PCInitiate and stateful capability.
+ */
+ @Test
+ public void testCasePcepReleaseTunnel2() {
+ Tunnel tunnel;
+ Path path;
+ List<Link> links = new ArrayList<Link>();
+
+ ProviderId pid = new ProviderId("pcep", PROVIDER_ID);
+
+ IpAddress srcIp = IpAddress.valueOf(0xB6024E22);
+ IpElementId srcElementId = IpElementId.ipElement(srcIp);
+
+ IpAddress dstIp = IpAddress.valueOf(0xB6024E21);
+ IpElementId dstElementId = IpElementId.ipElement(dstIp);
+
+ IpTunnelEndPoint ipTunnelEndPointSrc;
+ ipTunnelEndPointSrc = IpTunnelEndPoint.ipTunnelPoint(srcIp);
+
+ IpTunnelEndPoint ipTunnelEndPointDst;
+ ipTunnelEndPointDst = IpTunnelEndPoint.ipTunnelPoint(dstIp);
+
+ ConnectPoint src = new ConnectPoint(srcElementId, PortNumber.portNumber(10023));
+
+ ConnectPoint dst = new ConnectPoint(dstElementId, PortNumber.portNumber(10023));
+
+ Link link = DefaultLink.builder().providerId(pid).src(src).dst(dst)
+ .type(Link.Type.DIRECT).build();
+ links.add(link);
+
+ path = new DefaultPath(pid, links, 20, EMPTY);
+
+ tunnel = new DefaultTunnel(pid, ipTunnelEndPointSrc, ipTunnelEndPointDst, Tunnel.Type.MPLS,
+ new DefaultGroupId(0), TunnelId.valueOf(1), TunnelName.tunnelName("T123"),
+ path, EMPTY);
+
+ // for releasing tunnel tunnel should exist in db
+ PcepTunnelData pcepTunnelData = new PcepTunnelData(tunnel, path, RequestType.DELETE);
+ pcepTunnelData.setPlspId(1);
+ StatefulIPv4LspIdentidiersTlv tlv = new StatefulIPv4LspIdentidiersTlv(0, (short) 1, (short) 2, 3, 4);
+ pcepTunnelData.setStatefulIpv4IndentifierTlv(tlv);
+ tunnelProvider.pcepTunnelApiMapper.addToTunnelIdMap(pcepTunnelData);
+
+ tunnelProvider.pcepTunnelApiMapper.handleCreateTunnelRequestQueue(1, pcepTunnelData);
+
+ tunnelProvider.releaseTunnel(tunnel);
+ assertThat(tunnelProvider.pcepTunnelApiMapper.checkFromTunnelRequestQueue(1), is(false));
+ }
@After
public void tearDown() throws IOException {
diff --git a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepSetupTunnelProviderTest.java b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepSetupTunnelProviderTest.java
index bb25a5f..69d9d81 100644
--- a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepSetupTunnelProviderTest.java
+++ b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepSetupTunnelProviderTest.java
@@ -16,12 +16,17 @@
package org.onosproject.provider.pcep.tunnel.impl;
import static org.onosproject.net.DefaultAnnotations.EMPTY;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsNot.not;
+import static org.hamcrest.Matchers.nullValue;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.junit.After;
+import org.junit.Before;
import org.junit.Test;
import org.onlab.packet.IpAddress;
import org.onosproject.cfg.ComponentConfigAdapter;
@@ -40,26 +45,33 @@
import org.onosproject.net.PortNumber;
import org.onosproject.net.provider.ProviderId;
+/**
+ * Test for PCEP setup tunnel.
+ */
public class PcepSetupTunnelProviderTest {
- static final String PROVIDER_ID = "org.onosproject.provider.tunnel.pcep";
- PcepTunnelProvider tunnelProvider = new PcepTunnelProvider();
+ public static final String PROVIDER_ID = "org.onosproject.provider.tunnel.pcep";
+ private PcepTunnelProvider tunnelProvider = new PcepTunnelProvider();
private final TunnelProviderRegistryAdapter registry = new TunnelProviderRegistryAdapter();
private final PcepClientControllerAdapter controller = new PcepClientControllerAdapter();
private final PcepControllerAdapter ctl = new PcepControllerAdapter();
private final TunnelServiceAdapter tunnelService = new TunnelServiceAdapter();
- @Test
- public void testCasePcepSetupTunnel() {
-
+ @Before
+ public void setUp() throws IOException {
tunnelProvider.tunnelProviderRegistry = registry;
tunnelProvider.pcepClientController = controller;
tunnelProvider.controller = ctl;
tunnelProvider.cfgService = new ComponentConfigAdapter();
tunnelProvider.tunnelService = tunnelService;
tunnelProvider.activate();
+ }
-
+ /**
+ * Send PcInitiate message to PCC.
+ */
+ @Test
+ public void testCasePcepSetupTunnel() {
Tunnel tunnel;
Path path;
ProviderId pid = new ProviderId("pcep", PROVIDER_ID);
@@ -91,6 +103,46 @@
path, EMPTY);
tunnelProvider.setupTunnel(tunnel, path);
+ assertThat(tunnelProvider.pcepTunnelApiMapper, not(nullValue()));
+ }
+
+ /**
+ * Doesn't send PCInitiate message because PCC doesn't supports PCInitiate and stateful capability.
+ */
+ @Test
+ public void testCasePcepSetupTunnel2() {
+ Tunnel tunnel;
+ Path path;
+ ProviderId pid = new ProviderId("pcep", PROVIDER_ID);
+ List<Link> links = new ArrayList<Link>();
+ IpAddress srcIp = IpAddress.valueOf(0xC010103);
+ IpElementId srcElementId = IpElementId.ipElement(srcIp);
+
+ IpAddress dstIp = IpAddress.valueOf(0xC010102);
+ IpElementId dstElementId = IpElementId.ipElement(dstIp);
+
+ IpTunnelEndPoint ipTunnelEndPointSrc;
+ ipTunnelEndPointSrc = IpTunnelEndPoint.ipTunnelPoint(srcIp);
+
+ IpTunnelEndPoint ipTunnelEndPointDst;
+ ipTunnelEndPointDst = IpTunnelEndPoint.ipTunnelPoint(dstIp);
+
+ ConnectPoint src = new ConnectPoint(srcElementId, PortNumber.portNumber(10023));
+
+ ConnectPoint dst = new ConnectPoint(dstElementId, PortNumber.portNumber(10023));
+
+ Link link = DefaultLink.builder().providerId(pid).src(src).dst(dst)
+ .type(Link.Type.DIRECT).build();
+ links.add(link);
+
+ path = new DefaultPath(pid, links, 10, EMPTY);
+
+ tunnel = new DefaultTunnel(pid, ipTunnelEndPointSrc, ipTunnelEndPointDst, Tunnel.Type.MPLS,
+ new DefaultGroupId(0), TunnelId.valueOf(1), TunnelName.tunnelName("T123"),
+ path, EMPTY);
+
+ tunnelProvider.setupTunnel(tunnel, path);
+ assertThat(tunnelProvider.pcepTunnelApiMapper.checkFromTunnelRequestQueue(1), is(false));
}
@After
diff --git a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepTunnelProviderTest.java b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepTunnelProviderTest.java
index 9f64cea..f339096 100644
--- a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepTunnelProviderTest.java
+++ b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepTunnelProviderTest.java
@@ -42,8 +42,8 @@
public class PcepTunnelProviderTest {
- static final String PROVIDER_ID = "org.onosproject.provider.tunnel.pcep";
- PcepTunnelProvider tunnelProvider = new PcepTunnelProvider();
+ public static final String PROVIDER_ID = "org.onosproject.provider.tunnel.pcep";
+ private PcepTunnelProvider tunnelProvider = new PcepTunnelProvider();
private final TunnelProviderRegistryAdapter registry = new TunnelProviderRegistryAdapter();
private final PcepClientControllerAdapter controller = new PcepClientControllerAdapter();
private final PcepControllerAdapter ctl = new PcepControllerAdapter();
diff --git a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepUpdateTunnelProviderTest.java b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepUpdateTunnelProviderTest.java
index c5f97f6..e542510 100644
--- a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepUpdateTunnelProviderTest.java
+++ b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepUpdateTunnelProviderTest.java
@@ -15,6 +15,10 @@
*/
package org.onosproject.provider.pcep.tunnel.impl;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.nullValue;
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsNot.not;
import static org.onosproject.net.DefaultAnnotations.EMPTY;
import java.io.IOException;
@@ -22,6 +26,7 @@
import java.util.List;
import org.junit.After;
+import org.junit.Before;
import org.junit.Test;
import org.onlab.packet.IpAddress;
import org.onosproject.cfg.ComponentConfigAdapter;
@@ -41,20 +46,21 @@
import org.onosproject.net.provider.ProviderId;
import org.onosproject.pcepio.types.StatefulIPv4LspIdentidiersTlv;
-
+/**
+ * Test for PCEP update tunnel.
+ */
public class PcepUpdateTunnelProviderTest {
- static final String PROVIDER_ID = "org.onosproject.provider.tunnel.pcep";
- PcepTunnelProvider tunnelProvider = new PcepTunnelProvider();
+ public static final String PROVIDER_ID = "org.onosproject.provider.tunnel.pcep";
+ private PcepTunnelProvider tunnelProvider = new PcepTunnelProvider();
private final TunnelProviderRegistryAdapter registry = new TunnelProviderRegistryAdapter();
private final PcepClientControllerAdapter controller = new PcepClientControllerAdapter();
private final PcepControllerAdapter ctl = new PcepControllerAdapter();
private final PcepTunnelApiMapper pcepTunnelAPIMapper = new PcepTunnelApiMapper();
private final TunnelServiceAdapter tunnelService = new TunnelServiceAdapter();
-
- @Test
- public void testCasePcepUpdateTunnel() {
+ @Before
+ public void setUp() throws IOException {
tunnelProvider.tunnelProviderRegistry = registry;
tunnelProvider.pcepClientController = controller;
tunnelProvider.controller = ctl;
@@ -62,7 +68,13 @@
tunnelProvider.cfgService = new ComponentConfigAdapter();
tunnelProvider.tunnelService = tunnelService;
tunnelProvider.activate();
+ }
+ /**
+ * Send update message to PCC.
+ */
+ @Test
+ public void testCasePcepUpdateTunnel() {
Tunnel tunnel;
Path path;
ProviderId pid = new ProviderId("pcep", PROVIDER_ID);
@@ -103,6 +115,55 @@
tunnelProvider.pcepTunnelApiMapper.handleCreateTunnelRequestQueue(1, pcepTunnelData);
tunnelProvider.updateTunnel(tunnel, path);
+ assertThat(tunnelProvider.pcepTunnelApiMapper, not(nullValue()));
+ }
+
+ /**
+ * Doesn't send update message because PCC doesn't supports PCE stateful capability.
+ */
+ @Test
+ public void testCasePcepUpdateTunnel2() {
+ Tunnel tunnel;
+ Path path;
+ ProviderId pid = new ProviderId("pcep", PROVIDER_ID);
+ List<Link> links = new ArrayList<Link>();
+ IpAddress srcIp = IpAddress.valueOf(0xC010103);
+ IpElementId srcElementId = IpElementId.ipElement(srcIp);
+
+ IpAddress dstIp = IpAddress.valueOf(0xD010102);
+ IpElementId dstElementId = IpElementId.ipElement(dstIp);
+
+ IpTunnelEndPoint ipTunnelEndPointSrc;
+ ipTunnelEndPointSrc = IpTunnelEndPoint.ipTunnelPoint(srcIp);
+
+ IpTunnelEndPoint ipTunnelEndPointDst;
+ ipTunnelEndPointDst = IpTunnelEndPoint.ipTunnelPoint(dstIp);
+
+ ConnectPoint src = new ConnectPoint(srcElementId, PortNumber.portNumber(10023));
+
+ ConnectPoint dst = new ConnectPoint(dstElementId, PortNumber.portNumber(10023));
+
+ Link link = DefaultLink.builder().providerId(pid).src(src).dst(dst)
+ .type(Link.Type.DIRECT).build();
+ links.add(link);
+
+ path = new DefaultPath(pid, links, 20, EMPTY);
+
+ tunnel = new DefaultTunnel(pid, ipTunnelEndPointSrc, ipTunnelEndPointDst, Tunnel.Type.MPLS,
+ new DefaultGroupId(0), TunnelId.valueOf(1), TunnelName.tunnelName("T123"),
+ path, EMPTY);
+
+ // for updating tunnel tunnel should exist in db
+ PcepTunnelData pcepTunnelData = new PcepTunnelData(tunnel, path, RequestType.UPDATE);
+ pcepTunnelData.setPlspId(1);
+ StatefulIPv4LspIdentidiersTlv tlv = new StatefulIPv4LspIdentidiersTlv(0, (short) 1, (short) 2, 3, 4);
+ pcepTunnelData.setStatefulIpv4IndentifierTlv(tlv);
+ tunnelProvider.pcepTunnelApiMapper.addToTunnelIdMap(pcepTunnelData);
+
+ tunnelProvider.pcepTunnelApiMapper.handleCreateTunnelRequestQueue(1, pcepTunnelData);
+
+ tunnelProvider.updateTunnel(tunnel, path);
+ assertThat(tunnelProvider.pcepTunnelApiMapper.checkFromTunnelRequestQueue(1), is(false));
}
@After