[ONOS-4170] PCEP provider changes for LSPDB sync
Change-Id: I9229fec9d97dd46343cc809e33c92b9722ab7ed3
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
index 5e3996a..afeeae8 100644
--- 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
@@ -95,18 +95,32 @@
String channelId();
/**
- * To set the status of state synchronization.
+ * Sets the status of LSP state synchronization.
*
- * @param value to set the synchronization status
+ * @param syncStatus LSP synchronization status to be set
*/
- void setIsSyncComplete(boolean value);
+ void setLspDbSyncStatus(PcepSyncStatus syncStatus);
/**
- * Indicates the state synchronization status of this pcc.
+ * Indicates the LSP state synchronization status of this pcc.
*
- * @return true/false if the synchronization is completed/not completed
+ * @return LSP state synchronization status.
*/
- boolean isSyncComplete();
+ PcepSyncStatus lspDbSyncStatus();
+
+ /**
+ * Sets the status of label DB synchronization.
+ *
+ * @param syncStatus label DB synchronization status to be set
+ */
+ void setLabelDbSyncStatus(PcepSyncStatus syncStatus);
+
+ /**
+ * Indicates the label DB synchronization status of this pcc.
+ *
+ * @return label DB synchronization status.
+ */
+ PcepSyncStatus labelDbSyncStatus();
/**
* Sets capability negotiated during open message exchange.
diff --git a/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepSyncStatus.java b/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepSyncStatus.java
new file mode 100644
index 0000000..3c8ace5
--- /dev/null
+++ b/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepSyncStatus.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2016-present 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;
+
+/**
+ * Representation of PCEP database sync status on session establishment.
+ */
+public enum PcepSyncStatus {
+
+ /**
+ * Specifies that the DB state is not synchronized.
+ */
+ NOT_SYNCED(0),
+
+ /**
+ * Specifies that the DB state is currently undergoing synchronization.
+ */
+ IN_SYNC(1),
+
+ /**
+ * Specifies that the DB state synchronization is completed.
+ */
+ SYNCED(2);
+
+ int value;
+
+ /**
+ * Assign val with the value as the sync status.
+ *
+ * @param val sync status
+ */
+ PcepSyncStatus(int val) {
+ value = val;
+ }
+}
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 9f61b2a..744731f 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
@@ -169,6 +169,12 @@
}
}
+ /*
+ * If MPLS LSR id and PCEP session socket IP addresses are not same,
+ * the MPLS LSR id will be encoded in separate TLV.
+ * We always maintain session information based on LSR ids.
+ * The socket IP is stored in channel.
+ */
LinkedList<PcepValueType> optionalTlvs = pOpenmsg.getPcepOpenObject().getOptionalTlv();
for (PcepValueType optionalTlv : optionalTlvs) {
if (optionalTlv instanceof NodeAttributesTlv) {
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 23b6ba6..8328f2b 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
@@ -27,6 +27,7 @@
import org.onosproject.pcep.controller.ClientCapability;
import org.onosproject.pcep.controller.PccId;
import org.onosproject.pcep.controller.PcepPacketStats;
+import org.onosproject.pcep.controller.PcepSyncStatus;
import org.onosproject.pcep.controller.driver.PcepAgent;
import org.onosproject.pcep.controller.driver.PcepClientDriver;
import org.onosproject.pcepio.protocol.PcepFactories;
@@ -52,9 +53,10 @@
protected String channelId;
private boolean connected;
- protected boolean startDriverHandshakeCalled = false;
- protected boolean isHandShakeComplete = false;
- protected boolean isSyncComplete = false;
+ protected boolean startDriverHandshakeCalled;
+ protected boolean isHandShakeComplete;
+ private PcepSyncStatus lspDbSyncStatus;
+ private PcepSyncStatus labelDbSyncStatus;
private PccId pccId;
private PcepAgent agent;
@@ -175,13 +177,23 @@
}
@Override
- public void setIsSyncComplete(boolean value) {
- this.isSyncComplete = value;
+ public void setLspDbSyncStatus(PcepSyncStatus syncStatus) {
+ this.lspDbSyncStatus = syncStatus;
}
@Override
- public boolean isSyncComplete() {
- return isSyncComplete;
+ public PcepSyncStatus lspDbSyncStatus() {
+ return lspDbSyncStatus;
+ }
+
+ @Override
+ public void setLabelDbSyncStatus(PcepSyncStatus syncStatus) {
+ this.labelDbSyncStatus = syncStatus;
+ }
+
+ @Override
+ public PcepSyncStatus labelDbSyncStatus() {
+ return labelDbSyncStatus;
}
@Override
diff --git a/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLspObjectVer1.java b/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLspObjectVer1.java
index b7d9666..13469e9 100644
--- a/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLspObjectVer1.java
+++ b/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLspObjectVer1.java
@@ -48,7 +48,7 @@
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Object-Class | OT |Res|P|I| Object Length (bytes) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | PLSP-ID | Flag C| O|A|R|S|D|
+ | PLSP-ID | Flag |C| O|A|R|S|D|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// TLVs //
| |
@@ -116,6 +116,7 @@
* @param bRFlag R flag
* @param bSFlag S flag
* @param bDFlag D flag
+ * @param bCFlag C flag
* @param llOptionalTlv list of optional tlv
*/
public PcepLspObjectVer1(PcepObjectHeader lspObjHeader, int iPlspId, byte yOFlag, boolean bAFlag, boolean bRFlag,
@@ -294,6 +295,9 @@
}
int iTemp = iPlspId << PLSPID_SHIFT_VALUE;
+
+ iTemp = iTemp | (((bCFlag) ? BIT_SET : BIT_RESET) << CFLAG_SHIFT_VALUE);
+
iTemp = iTemp | (yOFlag << OFLAG_SHIFT_VALUE);
byte bFlag;
iTemp = bAFlag ? (iTemp | AFLAG_TEMP_SHIFT_VALUE) : iTemp;
diff --git a/providers/pcep/tunnel/src/main/java/org/onosproject/provider/pcep/tunnel/impl/PcepAnnotationKeys.java b/providers/pcep/tunnel/src/main/java/org/onosproject/provider/pcep/tunnel/impl/PcepAnnotationKeys.java
index 5b9ef66..63ad05d 100644
--- a/providers/pcep/tunnel/src/main/java/org/onosproject/provider/pcep/tunnel/impl/PcepAnnotationKeys.java
+++ b/providers/pcep/tunnel/src/main/java/org/onosproject/provider/pcep/tunnel/impl/PcepAnnotationKeys.java
@@ -51,4 +51,9 @@
* Annotation key for the LSP id assigned per tunnel.
*/
public static final String LOCAL_LSP_ID = "localLspId";
+
+ /**
+ * Annotation key for the identification of initiated LSP.
+ */
+ public static final String PCE_INIT = "pceInit";
}
diff --git a/providers/pcep/tunnel/src/main/java/org/onosproject/provider/pcep/tunnel/impl/PcepTunnelApiMapper.java b/providers/pcep/tunnel/src/main/java/org/onosproject/provider/pcep/tunnel/impl/PcepTunnelApiMapper.java
index 027a9a2..97cdce6 100644
--- a/providers/pcep/tunnel/src/main/java/org/onosproject/provider/pcep/tunnel/impl/PcepTunnelApiMapper.java
+++ b/providers/pcep/tunnel/src/main/java/org/onosproject/provider/pcep/tunnel/impl/PcepTunnelApiMapper.java
@@ -18,7 +18,6 @@
import java.util.HashMap;
import java.util.Map;
-import org.apache.commons.collections.map.MultiKeyMap;
import org.onosproject.incubator.net.tunnel.TunnelId;
import org.onosproject.incubator.net.tunnel.TunnelProviderService;
import org.slf4j.Logger;
@@ -40,8 +39,6 @@
private Map<Integer, PcepTunnelData> tunnelDB;
// Map to store the tunnel ids, given by core and given by pcc.
private Map<TunnelId, Integer> tunnelIdMap;
- //Map to store all the learnt tunnels.
- private MultiKeyMap pccTunnelDB = new MultiKeyMap();
TunnelProviderService tunnelApiMapperservice;
@@ -193,14 +190,4 @@
boolean retValue = tunnelDB.containsKey((new Integer(value)));
return retValue;
}
-
- /**
- * Add Learnt tunnels to pcc tunnel DB.
- *
- * @param pcepTunnelData pcep tunnel data
- */
- public void addPccTunnelDB(PcepTunnelData pcepTunnelData) {
- pccTunnelDB.put(pcepTunnelData.statefulIpv4IndentifierTlv().getTunnelId() & 0xFFFFL,
- pcepTunnelData.statefulIpv4IndentifierTlv().getIpv4IngressAddress(), pcepTunnelData);
- }
}
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 0ac46a9..cb1922a 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
@@ -73,6 +73,7 @@
import org.onosproject.pcep.controller.PcepClientController;
import org.onosproject.pcep.controller.PcepClientListener;
import org.onosproject.pcep.controller.PcepEventListener;
+import org.onosproject.pcep.controller.PcepSyncStatus;
import org.onosproject.pcepio.exceptions.PcepParseException;
import org.onosproject.pcepio.protocol.PcInitiatedLspRequest;
import org.onosproject.pcepio.protocol.PcepAttribute;
@@ -98,6 +99,7 @@
import org.slf4j.Logger;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Dictionary;
@@ -105,6 +107,7 @@
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
+import java.util.Map;
import java.util.Optional;
import static com.google.common.base.Preconditions.checkNotNull;
@@ -116,15 +119,20 @@
import static org.onosproject.net.PortNumber.portNumber;
import static org.onosproject.pcep.api.PcepDpid.uri;
import static org.onosproject.provider.pcep.tunnel.impl.LspType.WITH_SIGNALLING;
+import static org.onosproject.provider.pcep.tunnel.impl.LspType.SR_WITHOUT_SIGNALLING;
import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.BANDWIDTH;
import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.LOCAL_LSP_ID;
import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.LSP_SIG_TYPE;
import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.PCC_TUNNEL_ID;
import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.PLSP_ID;
+import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.PCE_INIT;
import static org.onosproject.provider.pcep.tunnel.impl.RequestType.CREATE;
import static org.onosproject.provider.pcep.tunnel.impl.RequestType.DELETE;
import static org.onosproject.provider.pcep.tunnel.impl.RequestType.LSP_STATE_RPT;
import static org.onosproject.provider.pcep.tunnel.impl.RequestType.UPDATE;
+import static org.onosproject.pcep.controller.PcepSyncStatus.IN_SYNC;
+import static org.onosproject.pcep.controller.PcepSyncStatus.SYNCED;
+import static org.onosproject.incubator.net.tunnel.Tunnel.State.UNSTABLE;
import static org.slf4j.LoggerFactory.getLogger;
/**
@@ -174,6 +182,10 @@
protected PcepTunnelApiMapper pcepTunnelApiMapper = new PcepTunnelApiMapper();
private static final int DEFAULT_BANDWIDTH_VALUE = 10;
+ private Map<IpAddress, Map<TunnelId, Tunnel>> preSyncLspDbMap = new HashMap<>();
+ private Map<IpAddress, List<Tunnel>> syncCompleteDeleteList = new HashMap<>();
+ private Map<IpAddress, List<Tunnel>> syncCompleteUpdateList = new HashMap<>();
+
/**
* Creates a Tunnel provider.
*/
@@ -1089,13 +1101,39 @@
// Check the sync status
if (lspObj.getSFlag()) {
- handleSyncReport(stateRpt);
+ if (pcepClientController.getClient(pccId).lspDbSyncStatus() != IN_SYNC) {
+ pcepClientController.getClient(pccId).setLspDbSyncStatus(IN_SYNC);
+
+ // On starting LSP-DB sync, store LSP DB locally for this PCC.
+ Map<TunnelId, Tunnel> preSyncLspDb = new HashMap<>();
+ Collection<Tunnel> queriedTunnels = tunnelService.queryTunnel(MPLS);
+
+ for (Tunnel tunnel : queriedTunnels) {
+ if (((IpTunnelEndPoint) tunnel.src()).ip().equals(pccId.ipAddress())) {
+ preSyncLspDb.put(tunnel.tunnelId(), tunnel);
+ }
+ }
+
+ preSyncLspDbMap.put(pccId.ipAddress(), preSyncLspDb);
+ syncCompleteDeleteList.put(pccId.ipAddress(), new LinkedList<>());
+ syncCompleteUpdateList.put(pccId.ipAddress(), new LinkedList<>());
+ }
+ handleRptWithoutSrpId(stateRpt, pccId, IN_SYNC);
continue;
- } else if (!pcepClientController.getClient(pccId).isSyncComplete()) {
- // sync is done
- pcepClientController.getClient(pccId).setIsSyncComplete(true);
+
+ } else if (pcepClientController.getClient(pccId).lspDbSyncStatus() == IN_SYNC) {
+ // If sync flag is not set in the msg, and the
+ // previous state was "in sync" means this is
+ // end of sync message. PCRpt for end of sync
+ // does not carry any LSP report.
+ pcepClientController.getClient(pccId).setLspDbSyncStatus(SYNCED);
+ handleEndOfSyncAction(pccId);
continue;
}
+
+ // For PCRpt without matching SRP id not during LSPDB sync.
+ handleRptWithoutSrpId(stateRpt, pccId, SYNCED);
+ continue;
}
handleReportMessage(srpId, lspObj, stateRpt);
@@ -1121,11 +1159,6 @@
ProviderId providerId = new ProviderId("pcep", PROVIDER_ID);
PcepTunnelData pcepTunnelData = pcepTunnelApiMapper.getDataFromTunnelRequestQueue(srpId);
- if (pcepTunnelData == null) {
- handleRptWithoutSrpId(stateRpt);
- return;
- }
-
// store the values required from report message
pcepTunnelData.setPlspId(lspObj.getPlspId());
pcepTunnelData.setLspAFlag(lspObj.getAFlag());
@@ -1176,117 +1209,43 @@
pcepTunnelApiMapper.handleUpdateTunnelRequestQueue(srpId, pcepTunnelData);
}
+ PcepLspStatus pcepLspStatus = PcepLspStatus.values()[lspObj.getOFlag()];
+
if (lspObj.getRFlag()) {
tunnelRemoved(td);
} else {
- State tunnelState = PcepLspStatus
- .getTunnelStatusFromLspStatus(PcepLspStatus.values()[lspObj.getOFlag()]);
+ State tunnelState = PcepLspStatus.getTunnelStatusFromLspStatus(pcepLspStatus);
tunnelUpdated(td, tunnelState);
}
+
+ // SR-TE also needs PCUpd msg after receiving PCRpt with status GOING-UP even
+ // though there are no labels to download for SR-TE.
+ if ((pcepLspStatus == PcepLspStatus.GOING_UP)
+ && (LspType.valueOf(tunnel.annotations().value(LSP_SIG_TYPE)) == SR_WITHOUT_SIGNALLING)) {
+ updateTunnel(tunnel, tunnel.path());
+ }
}
- /**
- * Handles asynchronous report messages from PCC when LSPDB sync is not in progress.
- *
- * @param stateRpt parsed PCEP report msg.
- */
- private void handleRptWithoutSrpId(PcepStateReport stateRpt) {
+ private void handleRptWithoutSrpId(PcepStateReport stateRpt, PccId pccId, PcepSyncStatus syncStatus) {
ProviderId providerId = new ProviderId("pcep", PROVIDER_ID);
- StatefulIPv4LspIdentifiersTlv ipv4LspTlv = null;
-
- PcepLspObject lspObj = stateRpt.getLspObject();
- ListIterator<PcepValueType> listTlvIterator = lspObj.getOptionalTlv().listIterator();
-
- while (listTlvIterator.hasNext()) {
- PcepValueType tlv = listTlvIterator.next();
- if (tlv.getType() == StatefulIPv4LspIdentifiersTlv.TYPE) {
- ipv4LspTlv = (StatefulIPv4LspIdentifiersTlv) tlv;
- break;
- }
- }
-
- checkNotNull(ipv4LspTlv);
-
- IpTunnelEndPoint tunnelEndPointSrc = IpTunnelEndPoint.ipTunnelPoint(IpAddress.valueOf(ipv4LspTlv
- .getIpv4IngressAddress()));
- IpTunnelEndPoint tunnelEndPointDst = IpTunnelEndPoint.ipTunnelPoint(IpAddress.valueOf(ipv4LspTlv
- .getIpv4EgressAddress()));
-
- Collection<Tunnel> tunnelQueryResult = tunnelService.queryTunnel(tunnelEndPointSrc, tunnelEndPointDst);
-
- Tunnel tunnel = null;
- // Asynchronous status change message from PCC for LSP reported earlier.
- for (Tunnel tunnelObj : tunnelQueryResult) {
- if ((tunnelObj.annotations().value(PLSP_ID) == null)
- || (tunnelObj.annotations().value(LOCAL_LSP_ID) == null)) {
- /*
- * Can skip this tunnel as this is one for which PCE has
- * sent PCInit/PCUpd msg and waiting for a PCRpt.
- */
- continue;
- }
-
- if ((Integer.valueOf(tunnelObj.annotations().value(PLSP_ID)) == lspObj.getPlspId())
- && (Integer.valueOf(tunnelObj.annotations().value(LOCAL_LSP_ID))
- == ipv4LspTlv.getLspId())) {
- tunnel = tunnelObj;
- break;
- }
- }
-
- // Status report for a new LSP when LSPDB sync was already completed sometime.
- // No need to add the tunnel if msg is for remove but store doesn't have an entry.
- if (tunnel == null) {
- if (!lspObj.getRFlag()) {
- handleSyncReport(stateRpt);
- }
- return;
- }
-
- DefaultTunnelDescription td = new DefaultTunnelDescription(tunnel.tunnelId(), tunnel.src(),
- tunnel.dst(), tunnel.type(), tunnel.groupId(),
- providerId, tunnel.tunnelName(), tunnel.path(),
- (SparseAnnotations) tunnel.annotations());
-
- if (lspObj.getRFlag()) {
- tunnelRemoved(td); // This will happen only for PCC initiated tunnels.
- } else {
- State tunnelState = PcepLspStatus
- .getTunnelStatusFromLspStatus(PcepLspStatus.values()[lspObj.getOFlag()]);
- tunnelUpdated(td, tunnelState);
- }
- }
-
- /**
- * Handles sync report received from pcc.
- *
- * @param stateRpt pcep state report
- */
- private void handleSyncReport(PcepStateReport stateRpt) {
- PcepLspObject lspObj = stateRpt.getLspObject();
PcepStateReport.PcepMsgPath msgPath = stateRpt.getMsgPath();
checkNotNull(msgPath);
PcepEroObject eroObj = msgPath.getEroObject();
if (eroObj == null) {
- log.debug("ERO object is null in sate report");
+ log.error("ERO object is null in report message.");
return;
}
+ Path path = buildPathFromEroObj(eroObj, providerId);
+
int bandwidth = 0;
-
- log.debug("Handle Sync report received from PCC.");
-
- if (0 == lspObj.getOFlag()) {
- log.warn("The PCC reported tunnel is in down state");
- }
- log.debug("Sync report received");
-
if (msgPath.getBandwidthObject() != null) {
bandwidth = msgPath.getBandwidthObject().getBandwidth();
}
- // To carry PST TLV, SRP object can be present with value 0 even
- // when PCRpt is
- // not in response to any action from PCE.
+ /*
+ * To carry PST TLV, SRP object can be present with value 0 even when PCRpt is not in response to any action
+ * from PCE.
+ */
PcepSrpObject srpObj = stateRpt.getSrpObject();
LspType lspType = WITH_SIGNALLING;
@@ -1308,7 +1267,164 @@
}
}
- buildAndStorePcepTunnelData(lspObj, eroObj, bandwidth, lspType);
+ PcepLspObject lspObj = stateRpt.getLspObject();
+ ListIterator<PcepValueType> listTlvIterator = lspObj.getOptionalTlv().listIterator();
+ StatefulIPv4LspIdentifiersTlv ipv4LspIdenTlv = null;
+ SymbolicPathNameTlv pathNameTlv = null;
+
+ while (listTlvIterator.hasNext()) {
+ PcepValueType tlv = listTlvIterator.next();
+ switch (tlv.getType()) {
+ case StatefulIPv4LspIdentifiersTlv.TYPE:
+ ipv4LspIdenTlv = (StatefulIPv4LspIdentifiersTlv) tlv;
+ break;
+
+ case SymbolicPathNameTlv.TYPE:
+ pathNameTlv = (SymbolicPathNameTlv) tlv;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ /*
+ * Draft says: The LSP-IDENTIFIERS TLV MUST be included in the LSP object in PCRpt messages for
+ * RSVP-signaled LSPs. For ONOS PCECC implementation, it is mandatory.
+ */
+ if (ipv4LspIdenTlv == null) {
+ log.error("Stateful IPv4 identifier TLV is null in PCRpt msg.");
+ return;
+ }
+
+ IpTunnelEndPoint tunnelEndPointSrc = IpTunnelEndPoint
+ .ipTunnelPoint(IpAddress.valueOf(ipv4LspIdenTlv.getIpv4IngressAddress()));
+ IpTunnelEndPoint tunnelEndPointDst = IpTunnelEndPoint
+ .ipTunnelPoint(IpAddress.valueOf(ipv4LspIdenTlv.getIpv4EgressAddress()));
+ Collection<Tunnel> tunnelQueryResult = tunnelService.queryTunnel(tunnelEndPointSrc, tunnelEndPointDst);
+
+ Tunnel tunnel = null;
+ // Asynchronous status change message from PCC for LSP reported earlier.
+ for (Tunnel tunnelObj : tunnelQueryResult) {
+ if (tunnelObj.annotations().value(PLSP_ID) == null) {
+ /*
+ * PLSP_ID is null while Tunnel is created at PCE and PCInit msg carries it as 0. It is allocated by
+ * PCC and in that case it becomes the first PCRpt msg from PCC for this LSP, and hence symbolic
+ * path name must be carried in the PCRpt msg. Draft says: The SYMBOLIC-PATH-NAME TLV "MUST" be
+ * included in the LSP object in the LSP State Report (PCRpt) message when during a given PCEP
+ * session an LSP is "first" reported to a PCE.
+ */
+ if ((pathNameTlv != null)
+ && Arrays.equals(tunnelObj.tunnelName().value().getBytes(), pathNameTlv.getValue())) {
+ tunnel = tunnelObj;
+ break;
+ }
+ continue;
+ }
+
+ if ((Integer.valueOf(tunnelObj.annotations().value(PLSP_ID)) == lspObj.getPlspId()) && (Integer
+ .valueOf(tunnelObj.annotations().value(LOCAL_LSP_ID)) == ipv4LspIdenTlv.getLspId())) {
+ tunnel = tunnelObj;
+ break;
+ }
+ }
+
+ DefaultTunnelDescription td;
+ State tunnelState = PcepLspStatus.getTunnelStatusFromLspStatus(PcepLspStatus.values()[lspObj.getOFlag()]);
+ if (tunnel == null) {
+ if (lspObj.getRFlag()) {
+ /*
+ * If PCC sends remove message and for any reason PCE does not have that entry, simply discard the
+ * message. Or if PCRpt for initiated LSP received and PCE doesn't know, then too discard.
+ */
+ return;
+ }
+
+ if (lspObj.getCFlag()) {
+ /*
+ * While in sync, if PCRpt is received for PCE init LSP and PCE doesn't have entry, mark to send
+ * delete message on end of sync.
+ */
+ SparseAnnotations annotations = DefaultAnnotations.builder()
+ .set(BANDWIDTH, (new Integer(bandwidth)).toString())
+ .set(LSP_SIG_TYPE, lspType.name())
+ .set(PCC_TUNNEL_ID, String.valueOf(ipv4LspIdenTlv.getTunnelId()))
+ .set(PLSP_ID, String.valueOf(lspObj.getPlspId()))
+ .set(LOCAL_LSP_ID, String.valueOf(ipv4LspIdenTlv.getLspId())).build();
+
+ // Gnenerate tunnel id for the temporary tunnel.
+ String onosTunnelId = "PCC" + String.valueOf(ipv4LspIdenTlv.getTunnelId());
+ Tunnel tunnelToBeDeleted = new DefaultTunnel(providerId, tunnelEndPointSrc, tunnelEndPointDst, MPLS,
+ new DefaultGroupId(0), TunnelId.valueOf(onosTunnelId),
+ TunnelName.tunnelName(String
+ .valueOf(pathNameTlv.getValue())),
+ path, annotations);
+
+ /*
+ * Need to send PCInitiate delete msg for a tunnel which does not exist at PCE. For that some dummy
+ * data-structures need to be populated.
+ */
+ PcepTunnelData pcepTunnelData = new PcepTunnelData(tunnelToBeDeleted, path, RequestType.DELETE);
+ pcepTunnelData.setPlspId(lspObj.getPlspId());
+ pcepTunnelData.setStatefulIpv4IndentifierTlv(ipv4LspIdenTlv);
+ pcepTunnelApiMapper.addToTunnelIdMap(pcepTunnelData);
+ pcepTunnelApiMapper.handleCreateTunnelRequestQueue(0, pcepTunnelData);
+
+ /*
+ * Add to the list of tunnels for which PCInit delete will be sent at the end of sync.
+ */
+ List<Tunnel> tunnelToBeDeletedList = syncCompleteDeleteList.get(pccId.ipAddress());
+ tunnelToBeDeletedList.add(tunnelToBeDeleted);
+ syncCompleteDeleteList.put(pccId.ipAddress(), tunnelToBeDeletedList);
+ return;
+ }
+
+ SparseAnnotations annotations = DefaultAnnotations.builder()
+ .set(BANDWIDTH, (new Integer(bandwidth)).toString())
+ .set(LSP_SIG_TYPE, lspType.name())
+ .set(PCC_TUNNEL_ID, String.valueOf(ipv4LspIdenTlv.getTunnelId()))
+ .set(PLSP_ID, String.valueOf(lspObj.getPlspId()))
+ .set(LOCAL_LSP_ID, String.valueOf(ipv4LspIdenTlv.getLspId())).build();
+
+ td = new DefaultTunnelDescription(null, tunnelEndPointSrc, tunnelEndPointDst, MPLS,
+ new DefaultGroupId(0), providerId,
+ TunnelName.tunnelName(String.valueOf(pathNameTlv.getValue())), path,
+ annotations);
+
+ TunnelId tId = tunnelAdded(td, tunnelState);
+ Tunnel tunnelInserted = new DefaultTunnel(providerId, tunnelEndPointSrc, tunnelEndPointDst, MPLS,
+ tunnelState, new DefaultGroupId(0), tId,
+ TunnelName.tunnelName(String.valueOf(pathNameTlv.getValue())),
+ path, annotations);
+
+ PcepTunnelData pcepTunnelData = new PcepTunnelData(tunnelInserted, path, LSP_STATE_RPT);
+ pcepTunnelData.setStatefulIpv4IndentifierTlv(ipv4LspIdenTlv);
+ pcepTunnelApiMapper.addToTunnelIdMap(pcepTunnelData);
+ return;
+ }
+
+ if ((syncStatus == IN_SYNC) && (lspObj.getCFlag()) && (tunnelState != tunnel.state())) {
+ // Mark to send PCUpd msg with state known at PCE.
+ List<Tunnel> tunnelToBeUpdateList = syncCompleteUpdateList.get(pccId.ipAddress());
+ tunnelToBeUpdateList.add(tunnel);
+ syncCompleteUpdateList.put(pccId.ipAddress(), tunnelToBeUpdateList);
+ return;
+ }
+
+ td = new DefaultTunnelDescription(tunnel.tunnelId(), tunnel.src(), tunnel.dst(),
+ tunnel.type(), tunnel.groupId(), providerId,
+ tunnel.tunnelName(), tunnel.path(),
+ (SparseAnnotations) tunnel.annotations());
+
+ if (lspObj.getRFlag()) {
+ tunnelRemoved(td);
+ } else {
+ if (syncStatus == IN_SYNC) {
+ markLspDbEntryAsLatest(pccId, tunnel.tunnelId());
+ }
+ tunnelUpdated(td, tunnelState);
+ }
+ return;
}
/**
@@ -1323,7 +1439,7 @@
List<Link> links = new ArrayList<Link>();
LinkedList<PcepValueType> llSubObj = eroObj.getSubObjects();
if (0 == llSubObj.size()) {
- log.error("RRO in report message does not have hop information");
+ log.error("ERO in report message does not have hop information");
}
ListIterator<PcepValueType> tlvIterator = llSubObj.listIterator();
@@ -1361,71 +1477,6 @@
return new DefaultPath(providerId, links, 0, EMPTY);
}
- /**
- * To build pcepTunnelData and informs core about the PCC reported
- * tunnel.
- *
- * @param lspObj PCEP LSP object
- * @param eroObj PCEP ERO object
- * @param bandwidth bandwidth of tunnel
- * @param lspType path setup type/signaling type of the LSP.
- */
- private void buildAndStorePcepTunnelData(PcepLspObject lspObj, PcepEroObject eroObj, int bandwidth,
- LspType lspType) {
-
- ProviderId providerId = new ProviderId("pcep", PROVIDER_ID);
-
- // StatefulIPv4LspIdentidiersTlv in LSP object will have the source and destination address.
- StatefulIPv4LspIdentifiersTlv lspIdenTlv = null;
- SymbolicPathNameTlv pathNameTlv = null;
- LinkedList<PcepValueType> llOptionalTlv = lspObj.getOptionalTlv();
- ListIterator<PcepValueType> listIterator = llOptionalTlv.listIterator();
- while (listIterator.hasNext()) {
- PcepValueType tlv = listIterator.next();
- switch (tlv.getType()) {
- case StatefulIPv4LspIdentifiersTlv.TYPE:
- lspIdenTlv = (StatefulIPv4LspIdentifiersTlv) tlv;
- break;
- case SymbolicPathNameTlv.TYPE:
- pathNameTlv = (SymbolicPathNameTlv) tlv;
- break;
- default:
- // currently this tlv is not required
- }
- }
-
- IpTunnelEndPoint tunnelEndPointSrc;
- tunnelEndPointSrc = IpTunnelEndPoint.ipTunnelPoint(IpAddress.valueOf(lspIdenTlv.getIpv4IngressAddress()));
- IpTunnelEndPoint tunnelEndPointDst;
- tunnelEndPointDst = IpTunnelEndPoint.ipTunnelPoint(IpAddress.valueOf(lspIdenTlv.getIpv4EgressAddress()));
-
- Path path = buildPathFromEroObj(eroObj, providerId);
-
- SparseAnnotations annotations = DefaultAnnotations.builder()
- .set(BANDWIDTH, (new Integer(bandwidth)).toString())
- .set(LSP_SIG_TYPE, lspType.name())
- .set(PCC_TUNNEL_ID, String.valueOf(lspIdenTlv.getTunnelId()))
- .set(PLSP_ID, String.valueOf(lspObj.getPlspId()))
- .set(LOCAL_LSP_ID, String.valueOf(lspIdenTlv.getLspId())).build();
-
- DefaultTunnelDescription td = new DefaultTunnelDescription(null, tunnelEndPointSrc,
- tunnelEndPointDst, MPLS,
- new DefaultGroupId(0), providerId,
- TunnelName.tunnelName(pathNameTlv.toString()),
- path, annotations);
- State tunnelState = PcepLspStatus.getTunnelStatusFromLspStatus(PcepLspStatus.values()[lspObj.getOFlag()]);
- TunnelId tId = tunnelAdded(td, tunnelState);
-
- Tunnel tunnel = new DefaultTunnel(providerId, tunnelEndPointSrc, tunnelEndPointDst, MPLS,
- new DefaultGroupId(0), tId,
- TunnelName.tunnelName(pathNameTlv.toString()), path, annotations);
-
- PcepTunnelData pcepTunnelData = new PcepTunnelData(tunnel, path, LSP_STATE_RPT);
- pcepTunnelData.setStatefulIpv4IndentifierTlv(lspIdenTlv);
- pcepTunnelApiMapper.addPccTunnelDB(pcepTunnelData);
- pcepTunnelApiMapper.addToTunnelIdMap(pcepTunnelData);
- }
-
@Override
public void clientConnected(PccId pccId) {
// TODO
@@ -1448,4 +1499,83 @@
public Tunnel tunnelQueryById(TunnelId tunnelId) {
return service.tunnelQueryById(tunnelId);
}
+
+ /**
+ * Removes the entry from temporary copy of LSPDB, signifying its status as upto date.
+ *
+ * @param pccId the key for temporary LSPDB
+ * @param tunnelId the tunnel id for which information is updated.
+ */
+ private void markLspDbEntryAsLatest(PccId pccId, TunnelId tunnelId) {
+ checkNotNull(pccId);
+ checkNotNull(tunnelId);
+
+ Map<TunnelId, Tunnel> preSyncLspDb = preSyncLspDbMap.get(pccId.ipAddress());
+ checkNotNull(preSyncLspDb);
+
+ preSyncLspDb.remove(tunnelId);
+ preSyncLspDbMap.put(pccId.ipAddress(), preSyncLspDb);
+ }
+
+ /**
+ * Sends PCInit, PCInit(R) or PCUpd messages for initiated LSPs at the end
+ * of LSP DB sync based on actions decided while sync was in progress. Also
+ * triggers label DB sync.
+ *
+ * @param pccId the key for temporary DBs storing required end of sync
+ * actions.
+ */
+ private void handleEndOfSyncAction(PccId pccId) {
+
+ Map<TunnelId, Tunnel> preSyncLspDb = preSyncLspDbMap.get(pccId.ipAddress());
+ checkNotNull(preSyncLspDb);
+
+ for (Tunnel tunnel : preSyncLspDb.values()) {
+
+ TunnelDescription td = new DefaultTunnelDescription(tunnel.tunnelId(),
+ tunnel.src(), tunnel.dst(),
+ tunnel.type(),
+ tunnel.groupId(),
+ tunnel.providerId(),
+ tunnel.tunnelName(),
+ tunnel.path(),
+ (SparseAnnotations) tunnel.annotations());
+
+ if ((tunnel.annotations().value(PCE_INIT) == null)
+ || (tunnel.annotations().value(PCE_INIT).equals("false"))) {
+
+ tunnelRemoved(td);
+ } else {
+ // Send PCInit msg again after global reoptimization.
+ tunnelUpdated(td, UNSTABLE);
+
+ // To remove the old tunnel from store whose PLSPID is not
+ // recognized by ingress PCC.
+ tunnelRemoved(td);
+ }
+ }
+
+ List<Tunnel> tunnelsToBeDeletedList = syncCompleteDeleteList.get(pccId.ipAddress());
+ checkNotNull(tunnelsToBeDeletedList);
+ for (Tunnel tunnel: tunnelsToBeDeletedList) {
+ releaseTunnel(tunnel);
+ }
+
+ List<Tunnel> tunnelsToBeUpdatedList = syncCompleteUpdateList.get(pccId.ipAddress());
+ checkNotNull(tunnelsToBeUpdatedList);
+ for (Tunnel tunnel: tunnelsToBeUpdatedList) {
+ updateTunnel(tunnel, tunnel.path());
+ }
+
+ /* On end of sync, empty all temporary data structures. */
+ preSyncLspDbMap.remove(pccId.ipAddress());
+ syncCompleteDeleteList.remove(pccId.ipAddress());
+ syncCompleteUpdateList.remove(pccId.ipAddress());
+
+ // TODO: If SR capable, send a notification to
+ // PCE APP to start label DB sync.
+ if (true) {
+ pcepClientController.getClient(pccId).setLabelDbSyncStatus(IN_SYNC);
+ }
+ }
}
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 2f519ec..daf315a 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
@@ -24,6 +24,7 @@
import org.onosproject.pcep.controller.ClientCapability;
import org.onosproject.pcep.controller.PccId;
import org.onosproject.pcep.controller.PcepClient;
+import org.onosproject.pcep.controller.PcepSyncStatus;
import org.onosproject.pcepio.protocol.PcepFactories;
import org.onosproject.pcepio.protocol.PcepFactory;
import org.onosproject.pcepio.protocol.PcepMessage;
@@ -42,7 +43,8 @@
private ClientCapability capability;
private PcepVersion pcepVersion;
- private boolean syncCompleted;
+ private PcepSyncStatus lspDbSyncStatus;
+ private PcepSyncStatus labelDbSyncStatus;
/**
* Initialize instance with specified parameters.
@@ -109,13 +111,23 @@
}
@Override
- public final boolean isSyncComplete() {
- return syncCompleted;
+ public void setLspDbSyncStatus(PcepSyncStatus syncStatus) {
+ this.lspDbSyncStatus = syncStatus;
}
@Override
- public final void setIsSyncComplete(boolean value) {
- syncCompleted = value;
+ public PcepSyncStatus lspDbSyncStatus() {
+ return lspDbSyncStatus;
+ }
+
+ @Override
+ public void setLabelDbSyncStatus(PcepSyncStatus syncStatus) {
+ this.labelDbSyncStatus = syncStatus;
+ }
+
+ @Override
+ public PcepSyncStatus labelDbSyncStatus() {
+ return labelDbSyncStatus;
}
@Override
diff --git a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepTunnelAddedTest.java b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepTunnelAddedTest.java
index 76f2bb0..2abab75 100644
--- a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepTunnelAddedTest.java
+++ b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepTunnelAddedTest.java
@@ -25,6 +25,8 @@
import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.PCC_TUNNEL_ID;
import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.PLSP_ID;
import static org.onosproject.provider.pcep.tunnel.impl.LspType.WITHOUT_SIGNALLING_AND_WITHOUT_SR;
+import static org.onosproject.pcep.controller.PcepSyncStatus.SYNCED;
+import static org.onosproject.pcep.controller.PcepSyncStatus.IN_SYNC;
import java.io.IOException;
import java.util.Collection;
@@ -260,7 +262,7 @@
PccId pccId = PccId.pccId(IpAddress.valueOf(0x4e1f0400));
controller.getClient(pccId).setCapability(new ClientCapability(true, true, true));
- controller.getClient(pccId).setIsSyncComplete(true);
+ controller.getClient(pccId).setLspDbSyncStatus(SYNCED);
// Process update message.
controller.processClientMessage(pccId, message);
@@ -307,13 +309,291 @@
PcepMessage message = reader.readFrom(buffer);
PccId pccId = PccId.pccId(IpAddress.valueOf("1.1.1.1"));
- controller.getClient(pccId).setIsSyncComplete(true);
+ controller.getClient(pccId).setLspDbSyncStatus(SYNCED);
controller.getClient(pccId).setCapability(new ClientCapability(true, true, true));
controller.processClientMessage(pccId, message);
assertThat(registry.tunnelIdCounter, is((long) 1));
}
+ /**
+ * Tests LSPDB sync where PCC reports less LSPs than known by PCE and PCE deletes at the end of DB sync.
+ */
+ @Test
+ public void testCaseLspDbSync1() throws PcepParseException, PcepOutOfBoundMessageException {
+ /* Step 1 create 2 LSPs */
+ byte[] reportMsg1 = new byte[] {0x20, 0x0a, 0x00, (byte) 0x84,
+ 0x21, 0x10, 0x00, 0x14, //SRP object
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x1c, 0x00, 0x04, // PATH-SETUP-TYPE TLV
+ 0x00, 0x00, 0x00, 0x00,
+ 0x20, 0x10, 0x00, 0x24, 0x00, 0x00, 0x10, 0x19, // LSP object
+ 0x00, 0x11, 0x00, 0x04, 0x54, 0x31, 0x00, 0x00, // symbolic path TLV
+ 0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
+ 0x01, 0x01, 0x01, 0x01,
+ 0x00, 0x01, 0x00, 0x01,
+ 0x01, 0x01, 0x01, 0x01,
+ 0x05, 0x05, 0x05, 0x05,
+
+ 0x07, 0x10, 0x00, 0x14, //ERO object
+ 0x01, 0x08, (byte) 0x01, 0x01, 0x01, 0x01, 0x04, 0x00, // ERO IPv4 sub objects
+ 0x01, 0x08, (byte) 0x05, 0x05, 0x05, 0x05, 0x04, 0x00,
+
+ 0x08, 0x10, 0x00, 0x34, //RRO object
+ 0x01, 0x08, 0x11, 0x01, 0x01, 0x01, 0x04, 0x00, // RRO IPv4 sub objects
+ 0x01, 0x08, 0x11, 0x01, 0x01, 0x02, 0x04, 0x00,
+ 0x01, 0x08, 0x06, 0x06, 0x06, 0x06, 0x04, 0x00,
+ 0x01, 0x08, 0x12, 0x01, 0x01, 0x02, 0x04, 0x00,
+ 0x01, 0x08, 0x12, 0x01, 0x01, 0x01, 0x04, 0x00,
+ 0x01, 0x08, 0x05, 0x05, 0x05, 0x05, 0x04, 0x00
+ };
+
+ ChannelBuffer buffer1 = ChannelBuffers.dynamicBuffer();
+ buffer1.writeBytes(reportMsg1);
+
+ PcepMessageReader<PcepMessage> reader1 = PcepFactories.getGenericReader();
+ PcepMessage message1 = reader1.readFrom(buffer1);
+
+ PccId pccId = PccId.pccId(IpAddress.valueOf("1.1.1.1"));
+ controller.getClient(pccId).setCapability(new ClientCapability(true, true, true));
+ controller.processClientMessage(pccId, message1);
+
+ /* create 2nd LSP */
+ byte[] reportMsg2 = new byte[] {0x20, 0x0a, 0x00, (byte) 0x84,
+ 0x21, 0x10, 0x00, 0x14, //SRP object
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x1c, 0x00, 0x04, // PATH-SETUP-TYPE TLV
+ 0x00, 0x00, 0x00, 0x00,
+ 0x20, 0x10, 0x00, 0x24, 0x00, 0x00, 0x20, 0x19, // LSP object
+ 0x00, 0x11, 0x00, 0x04, 0x54, 0x31, 0x00, 0x00, // symbolic path TLV
+ 0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
+ 0x01, 0x01, 0x01, 0x01,
+ 0x00, 0x02, 0x00, 0x02,
+ 0x01, 0x01, 0x01, 0x01,
+ 0x05, 0x05, 0x05, 0x05,
+
+ 0x07, 0x10, 0x00, 0x14, //ERO object
+ 0x01, 0x08, (byte) 0x01, 0x01, 0x01, 0x01, 0x04, 0x00, // ERO IPv4 sub objects
+ 0x01, 0x08, (byte) 0x05, 0x05, 0x05, 0x05, 0x04, 0x00,
+
+ 0x08, 0x10, 0x00, 0x34, //RRO object
+ 0x01, 0x08, 0x11, 0x01, 0x01, 0x01, 0x04, 0x00, // RRO IPv4 sub objects
+ 0x01, 0x08, 0x11, 0x01, 0x01, 0x02, 0x04, 0x00,
+ 0x01, 0x08, 0x06, 0x06, 0x06, 0x06, 0x04, 0x00,
+ 0x01, 0x08, 0x12, 0x01, 0x01, 0x02, 0x04, 0x00,
+ 0x01, 0x08, 0x12, 0x01, 0x01, 0x01, 0x04, 0x00,
+ 0x01, 0x08, 0x05, 0x05, 0x05, 0x05, 0x04, 0x00
+ };
+
+ ChannelBuffer buffer2 = ChannelBuffers.dynamicBuffer();
+ buffer2.writeBytes(reportMsg2);
+
+ PcepMessageReader<PcepMessage> reader2 = PcepFactories.getGenericReader();
+ PcepMessage message2 = reader2.readFrom(buffer2);
+
+ controller.processClientMessage(pccId, message2);
+
+ /* Assert number of LSPs in DB to be 2. */
+ assertThat(registry.tunnelIdCounter, is((long) 2));
+
+ /* Step 2 send sync begin message and LSP 1. */
+ byte[] reportMsg3 = new byte[] {0x20, 0x0a, 0x00, (byte) 0x84,
+ 0x21, 0x10, 0x00, 0x14, //SRP object
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x1c, 0x00, 0x04, // PATH-SETUP-TYPE TLV
+ 0x00, 0x00, 0x00, 0x00,
+ 0x20, 0x10, 0x00, 0x24, 0x00, 0x00, 0x10, 0x1B, // LSP object
+ 0x00, 0x11, 0x00, 0x04, 0x54, 0x31, 0x00, 0x00, // symbolic path TLV
+ 0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
+ 0x01, 0x01, 0x01, 0x01,
+ 0x00, 0x01, 0x00, 0x01,
+ 0x01, 0x01, 0x01, 0x01,
+ 0x05, 0x05, 0x05, 0x05,
+
+ 0x07, 0x10, 0x00, 0x14, //ERO object
+ 0x01, 0x08, (byte) 0x01, 0x01, 0x01, 0x01, 0x04, 0x00, // ERO IPv4 sub objects
+ 0x01, 0x08, (byte) 0x05, 0x05, 0x05, 0x05, 0x04, 0x00,
+
+ 0x08, 0x10, 0x00, 0x34, //RRO object
+ 0x01, 0x08, 0x11, 0x01, 0x01, 0x01, 0x04, 0x00, // RRO IPv4 sub objects
+ 0x01, 0x08, 0x11, 0x01, 0x01, 0x02, 0x04, 0x00,
+ 0x01, 0x08, 0x06, 0x06, 0x06, 0x06, 0x04, 0x00,
+ 0x01, 0x08, 0x12, 0x01, 0x01, 0x02, 0x04, 0x00,
+ 0x01, 0x08, 0x12, 0x01, 0x01, 0x01, 0x04, 0x00,
+ 0x01, 0x08, 0x05, 0x05, 0x05, 0x05, 0x04, 0x00
+ };
+
+ ChannelBuffer buffer3 = ChannelBuffers.dynamicBuffer();
+ buffer3.writeBytes(reportMsg3);
+ PcepMessageReader<PcepMessage> reader3 = PcepFactories.getGenericReader();
+ PcepMessage message3 = reader3.readFrom(buffer3);
+ controller.processClientMessage(pccId, message3);
+
+ assertThat(controller.getClient(pccId).lspDbSyncStatus(), is(IN_SYNC));
+
+ /* Step 3 send end of sync marker */
+ byte[] reportMsg4 = new byte[] {0x20, 0x0a, 0x00, (byte) 0x24,
+ 0x20, 0x10, 0x00, 0x1C, // LSP object
+ 0x00, 0x00, 0x10, 0x19,
+ 0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x07, 0x10, 0x00, 0x04, //ERO object
+ };
+
+ ChannelBuffer buffer4 = ChannelBuffers.dynamicBuffer();
+ buffer4.writeBytes(reportMsg4);
+ PcepMessageReader<PcepMessage> reader4 = PcepFactories.getGenericReader();
+ PcepMessage message4 = reader4.readFrom(buffer4);
+ controller.processClientMessage(pccId, message4);
+
+ assertThat(controller.getClient(pccId).lspDbSyncStatus(), is(SYNCED));
+ }
+
+ /**
+ * Tests PCC PCRpt PCE initiated LSP which PCE doesn't know and hence should send PCInit delete msg.
+ */
+ @Test
+ public void testCaseLspDbSync2() throws PcepParseException, PcepOutOfBoundMessageException {
+ /* Step 1 create 2 LSPs */
+ byte[] reportMsg1 = new byte[] {0x20, 0x0a, 0x00, (byte) 0x84,
+ 0x21, 0x10, 0x00, 0x14, //SRP object
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x1c, 0x00, 0x04, // PATH-SETUP-TYPE TLV
+ 0x00, 0x00, 0x00, 0x00,
+ 0x20, 0x10, 0x00, 0x24, 0x00, 0x00, 0x10, 0x19, // LSP object
+ 0x00, 0x11, 0x00, 0x04, 0x54, 0x31, 0x00, 0x00, // symbolic path TLV
+ 0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
+ 0x01, 0x01, 0x01, 0x01,
+ 0x00, 0x01, 0x00, 0x01,
+ 0x01, 0x01, 0x01, 0x01,
+ 0x05, 0x05, 0x05, 0x05,
+
+ 0x07, 0x10, 0x00, 0x14, //ERO object
+ 0x01, 0x08, (byte) 0x01, 0x01, 0x01, 0x01, 0x04, 0x00, // ERO IPv4 sub objects
+ 0x01, 0x08, (byte) 0x05, 0x05, 0x05, 0x05, 0x04, 0x00,
+
+ 0x08, 0x10, 0x00, 0x34, //RRO object
+ 0x01, 0x08, 0x11, 0x01, 0x01, 0x01, 0x04, 0x00, // RRO IPv4 sub objects
+ 0x01, 0x08, 0x11, 0x01, 0x01, 0x02, 0x04, 0x00,
+ 0x01, 0x08, 0x06, 0x06, 0x06, 0x06, 0x04, 0x00,
+ 0x01, 0x08, 0x12, 0x01, 0x01, 0x02, 0x04, 0x00,
+ 0x01, 0x08, 0x12, 0x01, 0x01, 0x01, 0x04, 0x00,
+ 0x01, 0x08, 0x05, 0x05, 0x05, 0x05, 0x04, 0x00
+ };
+
+ ChannelBuffer buffer1 = ChannelBuffers.dynamicBuffer();
+ buffer1.writeBytes(reportMsg1);
+
+ PcepMessageReader<PcepMessage> reader1 = PcepFactories.getGenericReader();
+ PcepMessage message1 = reader1.readFrom(buffer1);
+
+ PccId pccId = PccId.pccId(IpAddress.valueOf("1.1.1.1"));
+ controller.getClient(pccId).setCapability(new ClientCapability(true, true, true));
+ controller.processClientMessage(pccId, message1);
+
+ /* create 2nd LSP */
+ byte[] reportMsg2 = new byte[] {0x20, 0x0a, 0x00, (byte) 0x84,
+ 0x21, 0x10, 0x00, 0x14, //SRP object
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x1c, 0x00, 0x04, // PATH-SETUP-TYPE TLV
+ 0x00, 0x00, 0x00, 0x00,
+ 0x20, 0x10, 0x00, 0x24, 0x00, 0x00, 0x20, 0x19, // LSP object
+ 0x00, 0x11, 0x00, 0x04, 0x54, 0x31, 0x00, 0x00, // symbolic path TLV
+ 0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
+ 0x01, 0x01, 0x01, 0x01,
+ 0x00, 0x02, 0x00, 0x02,
+ 0x01, 0x01, 0x01, 0x01,
+ 0x05, 0x05, 0x05, 0x05,
+
+ 0x07, 0x10, 0x00, 0x14, //ERO object
+ 0x01, 0x08, (byte) 0x01, 0x01, 0x01, 0x01, 0x04, 0x00, // ERO IPv4 sub objects
+ 0x01, 0x08, (byte) 0x05, 0x05, 0x05, 0x05, 0x04, 0x00,
+
+ 0x08, 0x10, 0x00, 0x34, //RRO object
+ 0x01, 0x08, 0x11, 0x01, 0x01, 0x01, 0x04, 0x00, // RRO IPv4 sub objects
+ 0x01, 0x08, 0x11, 0x01, 0x01, 0x02, 0x04, 0x00,
+ 0x01, 0x08, 0x06, 0x06, 0x06, 0x06, 0x04, 0x00,
+ 0x01, 0x08, 0x12, 0x01, 0x01, 0x02, 0x04, 0x00,
+ 0x01, 0x08, 0x12, 0x01, 0x01, 0x01, 0x04, 0x00,
+ 0x01, 0x08, 0x05, 0x05, 0x05, 0x05, 0x04, 0x00
+ };
+
+ ChannelBuffer buffer2 = ChannelBuffers.dynamicBuffer();
+ buffer2.writeBytes(reportMsg2);
+
+ PcepMessageReader<PcepMessage> reader2 = PcepFactories.getGenericReader();
+ PcepMessage message2 = reader2.readFrom(buffer2);
+
+ controller.processClientMessage(pccId, message2);
+
+ /* Assert number of LSPs in DB to be 2. */
+ assertThat(registry.tunnelIdCounter, is((long) 2));
+
+ /* Step 2 send sync begin message and LSP 1. */
+ byte[] reportMsg3 = new byte[] {0x20, 0x0a, 0x00, (byte) 0x84,
+ 0x21, 0x10, 0x00, 0x14, //SRP object
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x1c, 0x00, 0x04, // PATH-SETUP-TYPE TLV
+ 0x00, 0x00, 0x00, 0x00,
+ 0x20, 0x10, 0x00, 0x24, 0x00, 0x00, 0x10, (byte) 0x9B, // LSP object
+ 0x00, 0x11, 0x00, 0x04, 0x54, 0x31, 0x00, 0x00, // symbolic path TLV
+ 0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
+ 0x01, 0x01, 0x01, 0x01,
+ 0x00, 0x01, 0x00, 0x03,
+ 0x01, 0x01, 0x01, 0x01,
+ 0x05, 0x05, 0x05, 0x05,
+
+ 0x07, 0x10, 0x00, 0x14, //ERO object
+ 0x01, 0x08, (byte) 0x01, 0x01, 0x01, 0x01, 0x04, 0x00, // ERO IPv4 sub objects
+ 0x01, 0x08, (byte) 0x05, 0x05, 0x05, 0x05, 0x04, 0x00,
+
+ 0x08, 0x10, 0x00, 0x34, //RRO object
+ 0x01, 0x08, 0x11, 0x01, 0x01, 0x01, 0x04, 0x00, // RRO IPv4 sub objects
+ 0x01, 0x08, 0x11, 0x01, 0x01, 0x02, 0x04, 0x00,
+ 0x01, 0x08, 0x06, 0x06, 0x06, 0x06, 0x04, 0x00,
+ 0x01, 0x08, 0x12, 0x01, 0x01, 0x02, 0x04, 0x00,
+ 0x01, 0x08, 0x12, 0x01, 0x01, 0x01, 0x04, 0x00,
+ 0x01, 0x08, 0x05, 0x05, 0x05, 0x05, 0x04, 0x00
+ };
+
+ ChannelBuffer buffer3 = ChannelBuffers.dynamicBuffer();
+ buffer3.writeBytes(reportMsg3);
+ PcepMessageReader<PcepMessage> reader3 = PcepFactories.getGenericReader();
+ PcepMessage message3 = reader3.readFrom(buffer3);
+ controller.processClientMessage(pccId, message3);
+
+ assertThat(controller.getClient(pccId).lspDbSyncStatus(), is(IN_SYNC));
+
+ /* Step 3 send end of sync marker */
+ byte[] reportMsg4 = new byte[] {0x20, 0x0a, 0x00, (byte) 0x24,
+ 0x20, 0x10, 0x00, 0x1C, // LSP object
+ 0x00, 0x00, 0x10, 0x19,
+ 0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x07, 0x10, 0x00, 0x04, //ERO object
+ };
+
+ ChannelBuffer buffer4 = ChannelBuffers.dynamicBuffer();
+ buffer4.writeBytes(reportMsg4);
+ PcepMessageReader<PcepMessage> reader4 = PcepFactories.getGenericReader();
+ PcepMessage message4 = reader4.readFrom(buffer4);
+ controller.processClientMessage(pccId, message4);
+
+ assertThat(controller.getClient(pccId).lspDbSyncStatus(), is(SYNCED));
+ }
+
@After
public void tearDown() throws IOException {
tunnelProvider.deactivate();