Bgp and Pcep maintaiability
Change-Id: I2c14cc29d4900ef2f0fbffd4761b0d78e282910f
diff --git a/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/Controller.java b/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/Controller.java
index b7d1d52..92ea93a 100644
--- a/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/Controller.java
+++ b/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/Controller.java
@@ -20,8 +20,11 @@
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.net.InetSocketAddress;
-import java.util.HashMap;
import java.util.Map;
+import java.util.LinkedList;
+import java.util.TreeMap;
+import java.util.List;
+import java.util.HashMap;
import java.util.concurrent.Executors;
import org.jboss.netty.bootstrap.ServerBootstrap;
@@ -30,6 +33,7 @@
import org.jboss.netty.channel.group.DefaultChannelGroup;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
import org.onosproject.pcep.controller.PccId;
+import org.onosproject.pcep.controller.PcepCfg;
import org.onosproject.pcep.controller.PcepPacketStats;
import org.onosproject.pcep.controller.driver.PcepAgent;
import org.onosproject.pcep.controller.driver.PcepClientDriver;
@@ -48,7 +52,7 @@
private static final Logger log = LoggerFactory.getLogger(Controller.class);
private static final PcepFactory FACTORY1 = PcepFactories.getFactory(PcepVersion.PCEP_1);
-
+ private PcepCfg pcepConfig = new PcepConfig();
private ChannelGroup cg;
// Configuration options
@@ -60,12 +64,83 @@
private PcepAgent agent;
+ private Map<String, String> peerMap = new TreeMap<>();
+ private Map<String, List<String>> pcepExceptionMap = new TreeMap<>();
+ private Map<Integer, Integer> pcepErrorMsg = new TreeMap<>();
+ private Map<String, Byte> sessionMap = new TreeMap<>();
+ private LinkedList<String> pcepExceptionList = new LinkedList<String>();
+
private NioServerSocketChannelFactory execFactory;
// Perf. related configuration
private static final int SEND_BUFFER_SIZE = 4 * 1024 * 1024;
/**
+ * pcep session information.
+ *
+ * @param peerId id of the peer with which the session is being formed
+ * @param status pcep session status
+ * @param sessionId pcep session id
+ */
+ public void peerStatus(String peerId, String status, byte sessionId) {
+ if (peerId != null) {
+ peerMap.put(peerId, status);
+ sessionMap.put(peerId, sessionId);
+ } else {
+ log.debug("Peer Id is null");
+ }
+ }
+
+ /**
+ * Pcep session exceptions information.
+ *
+ * @param peerId id of the peer which has generated the exception
+ * @param exception pcep session exception
+ */
+ public void peerExceptions(String peerId, String exception) {
+ if (peerId != null) {
+ pcepExceptionList.add(exception);
+ pcepExceptionMap.put(peerId, pcepExceptionList);
+ } else {
+ log.debug("Peer Id is null");
+ }
+ if (pcepExceptionList.size() > 10) {
+ pcepExceptionList.clear();
+ pcepExceptionList.add(exception);
+ pcepExceptionMap.put(peerId, pcepExceptionList);
+ }
+ }
+
+ /**
+ * Create a map of pcep error messages received.
+ *
+ * @param peerId id of the peer which has sent the error message
+ * @param errorType error type of pcep error messgae
+ * @param errValue error value of pcep error messgae
+ */
+ public void peerErrorMsg(String peerId, Integer errorType, Integer errValue) {
+ if (peerId == null) {
+ pcepErrorMsg.put(errorType, errValue);
+ } else {
+ if (pcepErrorMsg.size() > 10) {
+ pcepErrorMsg.clear();
+ }
+ pcepErrorMsg.put(errorType, errValue);
+ }
+ }
+
+ /**
+ * Returns the pcep session details.
+ *
+ * @return pcep session details
+ */
+ public Map<String, Byte> mapSession() {
+ return this.sessionMap;
+ }
+
+
+
+ /**
* Returns factory version for processing pcep messages.
*
* @return instance of factory version
@@ -84,6 +159,33 @@
}
/**
+ * Returns the list of pcep peers with session information.
+ *
+ * @return pcep peer information
+ */
+ public Map<String, String> mapPeer() {
+ return this.peerMap;
+ }
+
+ /**
+ * Returns the list of pcep exceptions per peer.
+ *
+ * @return pcep exceptions
+ */
+ public Map<String, List<String>> exceptionsMap() {
+ return this.pcepExceptionMap;
+ }
+
+ /**
+ * Returns the type and value of pcep error messages.
+ *
+ * @return pcep error message
+ */
+ public Map<Integer, Integer> mapErrorMsg() {
+ return this.pcepErrorMsg;
+ }
+
+ /**
* Tell controller that we're ready to accept pcc connections.
*/
public void run() {
@@ -101,7 +203,7 @@
InetSocketAddress sa = new InetSocketAddress(pcepPort);
cg = new DefaultChannelGroup();
cg.add(bootstrap.bind(sa));
- log.info("Listening for PCC connection on {}", sa);
+ log.debug("Listening for PCC connection on {}", sa);
} catch (Exception e) {
throw new RuntimeException(e);
}
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 d2523f5..d557116 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
@@ -40,6 +40,7 @@
import org.onlab.packet.IpAddress;
import org.onosproject.pcep.controller.ClientCapability;
import org.onosproject.pcep.controller.PccId;
+import org.onosproject.pcep.controller.PcepCfg;
import org.onosproject.pcep.controller.driver.PcepClientDriver;
import org.onosproject.pcepio.exceptions.PcepParseException;
import org.onosproject.pcepio.protocol.PcepError;
@@ -87,7 +88,9 @@
// State needs to be volatile because the HandshakeTimeoutHandler
// needs to check if the handshake is complete
private volatile ChannelState state;
-
+ private String peerAddr;
+ private SocketAddress address;
+ private InetSocketAddress inetAddress;
// When a pcc client with a ip addresss is found (i.e we already have a
// connected client with the same ip), the new client is immediately
// disconnected. At that point netty callsback channelDisconnected() which
@@ -122,226 +125,38 @@
// Channel State Machine
//*************************
- /**
- * The state machine for handling the client/channel state. All state
- * transitions should happen from within the state machine (and not from other
- * parts of the code)
- */
- enum ChannelState {
- /**
- * Initial state before channel is connected.
- */
- INIT(false) {
-
- },
- /**
- * Once the session is established, wait for open message.
- */
- OPENWAIT(false) {
- @Override
- void processPcepMessage(PcepChannelHandler h, PcepMessage m) throws IOException, PcepParseException {
-
- log.info("Message received in OPEN WAIT State");
-
- //check for open message
- if (m.getType() != PcepType.OPEN) {
- // When the message type is not open message increment the wrong packet statistics
- h.processUnknownMsg();
- log.debug("message is not OPEN message");
- } else {
-
- h.pcepPacketStats.addInPacket();
- PcepOpenMsg pOpenmsg = (PcepOpenMsg) m;
- //Do Capability negotiation.
- h.capabilityNegotiation(pOpenmsg);
- log.debug("Sending handshake OPEN message");
- h.sessionId = pOpenmsg.getPcepOpenObject().getSessionId();
- h.pcepVersion = pOpenmsg.getPcepOpenObject().getVersion();
-
- //setting keepalive and deadTimer
- byte yKeepalive = pOpenmsg.getPcepOpenObject().getKeepAliveTime();
- byte yDeadTimer = pOpenmsg.getPcepOpenObject().getDeadTime();
- h.keepAliveTime = yKeepalive;
- if (yKeepalive < yDeadTimer) {
- h.deadTime = yDeadTimer;
- } else {
- if (DEADTIMER_MAXIMUM_VALUE > (yKeepalive * KEEPALIVE_MULTIPLE_FOR_DEADTIMER)) {
- h.deadTime = (byte) (yKeepalive * KEEPALIVE_MULTIPLE_FOR_DEADTIMER);
- } else {
- h.deadTime = DEADTIMER_MAXIMUM_VALUE;
- }
- }
-
- /*
- * 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();
- if (optionalTlvs != null) {
- for (PcepValueType optionalTlv : optionalTlvs) {
- if (optionalTlv instanceof NodeAttributesTlv) {
- List<PcepValueType> subTlvs = ((NodeAttributesTlv) optionalTlv)
- .getllNodeAttributesSubTLVs();
- if (subTlvs == null) {
- break;
- }
- for (PcepValueType subTlv : subTlvs) {
- if (subTlv instanceof IPv4RouterIdOfLocalNodeSubTlv) {
- h.thispccId = PccId.pccId(IpAddress
- .valueOf(((IPv4RouterIdOfLocalNodeSubTlv) subTlv).getInt()));
- break;
- }
- }
- break;
- }
- }
- }
-
- if (h.thispccId == null) {
- final SocketAddress address = h.channel.getRemoteAddress();
- if (!(address instanceof InetSocketAddress)) {
- throw new IOException("Invalid client connection. Pcc is indentifed based on IP");
- }
-
- final InetSocketAddress inetAddress = (InetSocketAddress) address;
- h.thispccId = PccId.pccId(IpAddress.valueOf(inetAddress.getAddress()));
- }
-
- h.sendHandshakeOpenMessage();
- h.pcepPacketStats.addOutPacket();
- h.setState(KEEPWAIT);
- }
- }
- },
- /**
- * Once the open messages are exchanged, wait for keep alive message.
- */
- KEEPWAIT(false) {
- @Override
- void processPcepMessage(PcepChannelHandler h, PcepMessage m) throws IOException, PcepParseException {
- log.info("message received in KEEPWAIT state");
- //check for keep alive message
- if (m.getType() != PcepType.KEEP_ALIVE) {
- // When the message type is not keep alive message increment the wrong packet statistics
- h.processUnknownMsg();
- log.error("message is not KEEPALIVE message");
- } else {
- // Set the client connected status
- h.pcepPacketStats.addInPacket();
- log.debug("sending keep alive message in KEEPWAIT state");
- h.pc = h.controller.getPcepClientInstance(h.thispccId, h.sessionId, h.pcepVersion,
- h.pcepPacketStats);
- //Get pc instance and set capabilities
- h.pc.setCapability(h.capability);
-
- // Initilialize DB sync status.
- h.pc.setLspDbSyncStatus(NOT_SYNCED);
- h.pc.setLabelDbSyncStatus(NOT_SYNCED);
-
- // set the status of pcc as connected
- h.pc.setConnected(true);
- h.pc.setChannel(h.channel);
-
- // set any other specific parameters to the pcc
- h.pc.setPcVersion(h.pcepVersion);
- h.pc.setPcSessionId(h.sessionId);
- h.pc.setPcKeepAliveTime(h.keepAliveTime);
- h.pc.setPcDeadTime(h.deadTime);
- int keepAliveTimer = h.keepAliveTime & BYTE_MASK;
- int deadTimer = h.deadTime & BYTE_MASK;
- if (0 == h.keepAliveTime) {
- h.deadTime = 0;
- }
- // handle keep alive and dead time
- if (keepAliveTimer != PcepPipelineFactory.DEFAULT_KEEP_ALIVE_TIME
- || deadTimer != PcepPipelineFactory.DEFAULT_DEAD_TIME) {
-
- h.channel.getPipeline().replace("idle", "idle",
- new IdleStateHandler(PcepPipelineFactory.TIMER, deadTimer, keepAliveTimer, 0));
- }
- log.debug("Dead timer : " + deadTimer);
- log.debug("Keep alive time : " + keepAliveTimer);
-
- //set the state handshake completion.
-
- h.sendKeepAliveMessage();
- h.pcepPacketStats.addOutPacket();
- h.setHandshakeComplete(true);
-
- if (!h.pc.connectClient()) {
- disconnectDuplicate(h);
- } else {
- h.setState(ESTABLISHED);
- //Session is established, add a network configuration with LSR id and device capabilities.
- h.addNode();
- }
- }
- }
- },
- /**
- * Once the keep alive messages are exchanged, the state is established.
- */
- ESTABLISHED(true) {
- @Override
- void processPcepMessage(PcepChannelHandler h, PcepMessage m) throws IOException, PcepParseException {
-
- //h.channel.getPipeline().remove("waittimeout");
- log.debug("Message received in established state " + m.getType());
- //dispatch the message
- h.dispatchMessage(m);
- }
- };
- private boolean handshakeComplete;
-
- ChannelState(boolean handshakeComplete) {
- this.handshakeComplete = handshakeComplete;
- }
-
- void processPcepMessage(PcepChannelHandler h, PcepMessage m) throws IOException, PcepParseException {
- // do nothing
- }
-
- /**
- * Is this a state in which the handshake has completed.
- *
- * @return true if the handshake is complete
- */
- public boolean isHandshakeComplete() {
- return this.handshakeComplete;
- }
-
- protected void disconnectDuplicate(PcepChannelHandler h) {
- log.error("Duplicated Pcc IP or incompleted cleanup - " + "disconnecting channel {}",
- h.getClientInfoString());
- h.duplicatePccIdFound = Boolean.TRUE;
- h.channel.disconnect();
- }
-
- /**
- * Sets handshake complete status.
- *
- * @param handshakeComplete status of handshake
- */
- public void setHandshakeComplete(boolean handshakeComplete) {
- this.handshakeComplete = handshakeComplete;
- }
-
- }
-
@Override
public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
channel = e.getChannel();
log.info("PCC connected from {}", channel.getRemoteAddress());
+ address = channel.getRemoteAddress();
+ if (!(address instanceof InetSocketAddress)) {
+ throw new IOException("Invalid peer connection.");
+ }
+
+ inetAddress = (InetSocketAddress) address;
+ peerAddr = IpAddress.valueOf(inetAddress.getAddress()).toString();
+
// Wait for open message from pcc client
setState(ChannelState.OPENWAIT);
+ controller.peerStatus(peerAddr, PcepCfg.State.OPENWAIT.toString(), sessionId);
}
@Override
public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
log.info("Pcc disconnected callback for pc:{}. Cleaning up ...", getClientInfoString());
+ controller.peerStatus(peerAddr, PcepCfg.State.DOWN.toString(), sessionId);
+
+ channel = e.getChannel();
+ address = channel.getRemoteAddress();
+ if (!(address instanceof InetSocketAddress)) {
+ throw new IOException("Invalid peer connection.");
+ }
+
+ inetAddress = (InetSocketAddress) address;
+ peerAddr = IpAddress.valueOf(inetAddress.getAddress()).toString();
+
if (thispccId != null) {
if (!duplicatePccIdFound) {
// if the disconnected client (on this ChannelHandler)
@@ -377,6 +192,7 @@
// OpenWait timer.
errMsg = getErrorMsg(PcepErrorDetailInfo.ERROR_TYPE_1, PcepErrorDetailInfo.ERROR_VALUE_2);
log.debug("Sending PCEP-ERROR message to PCC.");
+ controller.peerExceptions(peerAddr, e.getCause().toString());
channel.write(Collections.singletonList(errMsg));
channel.close();
state = ChannelState.INIT;
@@ -386,14 +202,17 @@
// KeepWait timer.
errMsg = getErrorMsg(PcepErrorDetailInfo.ERROR_TYPE_1, PcepErrorDetailInfo.ERROR_VALUE_7);
log.debug("Sending PCEP-ERROR message to PCC.");
+ controller.peerExceptions(peerAddr, e.getCause().toString());
channel.write(Collections.singletonList(errMsg));
channel.close();
state = ChannelState.INIT;
return;
}
} else if (e.getCause() instanceof ClosedChannelException) {
+ controller.peerExceptions(peerAddr, e.getCause().toString());
log.debug("Channel for pc {} already closed", getClientInfoString());
} else if (e.getCause() instanceof IOException) {
+ controller.peerExceptions(peerAddr, e.getCause().toString());
log.error("Disconnecting client {} due to IO Error: {}", getClientInfoString(), e.getCause().getMessage());
if (log.isDebugEnabled()) {
// still print stack trace if debug is enabled
@@ -401,6 +220,7 @@
}
channel.close();
} else if (e.getCause() instanceof PcepParseException) {
+ controller.peerExceptions(peerAddr, e.getCause().toString());
PcepParseException errMsgParse = (PcepParseException) e.getCause();
byte errorType = errMsgParse.getErrorType();
byte errorValue = errMsgParse.getErrorValue();
@@ -414,8 +234,10 @@
}
} else if (e.getCause() instanceof RejectedExecutionException) {
log.warn("Could not process message: queue full");
+ controller.peerExceptions(peerAddr, e.getCause().toString());
} else {
log.error("Error while processing message from client " + getClientInfoString() + "state " + this.state);
+ controller.peerExceptions(peerAddr, e.getCause().toString());
channel.close();
}
}
@@ -458,15 +280,6 @@
}
/**
- * To set the handshake status.
- *
- * @param handshakeComplete value is handshake status
- */
- public void setHandshakeComplete(boolean handshakeComplete) {
- this.state.setHandshakeComplete(handshakeComplete);
- }
-
- /**
* Is this a state in which the handshake has completed.
*
* @return true if the handshake is complete
@@ -476,6 +289,15 @@
}
/**
+ * To set the handshake status.
+ *
+ * @param handshakeComplete value is handshake status
+ */
+ public void setHandshakeComplete(boolean handshakeComplete) {
+ this.state.setHandshakeComplete(handshakeComplete);
+ }
+
+ /**
* To handle the pcep message.
*
* @param m pcep message
@@ -561,24 +383,24 @@
PcepValueType tlv = listIterator.next();
switch (tlv.getType()) {
- case PceccCapabilityTlv.TYPE:
- pceccCapability = true;
- if (((PceccCapabilityTlv) tlv).sBit()) {
- labelStackCapability = true;
- }
- break;
- case StatefulPceCapabilityTlv.TYPE:
- statefulPceCapability = true;
- StatefulPceCapabilityTlv stetefulPcCapTlv = (StatefulPceCapabilityTlv) tlv;
- if (stetefulPcCapTlv.getIFlag()) {
- pcInstantiationCapability = true;
- }
- break;
- case SrPceCapabilityTlv.TYPE:
- srCapability = true;
- break;
- default:
- continue;
+ case PceccCapabilityTlv.TYPE:
+ pceccCapability = true;
+ if (((PceccCapabilityTlv) tlv).sBit()) {
+ labelStackCapability = true;
+ }
+ break;
+ case StatefulPceCapabilityTlv.TYPE:
+ statefulPceCapability = true;
+ StatefulPceCapabilityTlv stetefulPcCapTlv = (StatefulPceCapabilityTlv) tlv;
+ if (stetefulPcCapTlv.getIFlag()) {
+ pcInstantiationCapability = true;
+ }
+ break;
+ case SrPceCapabilityTlv.TYPE:
+ srCapability = true;
+ break;
+ default:
+ continue;
}
}
this.capability = new ClientCapability(pceccCapability, statefulPceCapability, pcInstantiationCapability,
@@ -588,7 +410,7 @@
/**
* Send keep alive message.
*
- * @throws IOException when channel is disconnected
+ * @throws IOException when channel is disconnected
* @throws PcepParseException while building keep alive message
*/
private void sendKeepAliveMessage() throws IOException, PcepParseException {
@@ -638,22 +460,22 @@
llerrObj.add(errObj);
- //If Error caught in other than Openmessage
- LinkedList<PcepError> llPcepErr = new LinkedList<>();
+ //If Error caught in other than Openmessage
+ LinkedList<PcepError> llPcepErr = new LinkedList<>();
- PcepError pcepErr = factory1.buildPcepError()
- .setErrorObjList(llerrObj)
- .build();
+ PcepError pcepErr = factory1.buildPcepError()
+ .setErrorObjList(llerrObj)
+ .build();
- llPcepErr.add(pcepErr);
+ llPcepErr.add(pcepErr);
- PcepErrorInfo errInfo = factory1.buildPcepErrorInfo()
- .setPcepErrorList(llPcepErr)
- .build();
+ PcepErrorInfo errInfo = factory1.buildPcepErrorInfo()
+ .setPcepErrorList(llPcepErr)
+ .build();
- errMsg = factory1.buildPcepErrorMsg()
- .setPcepErrorInfo(errInfo)
- .build();
+ errMsg = factory1.buildPcepErrorMsg()
+ .setPcepErrorInfo(errInfo)
+ .build();
return errMsg;
}
@@ -690,4 +512,214 @@
}
}
}
+
+ /**
+ * The state machine for handling the client/channel state. All state
+ * transitions should happen from within the state machine (and not from other
+ * parts of the code)
+ */
+ enum ChannelState {
+ /**
+ * Initial state before channel is connected.
+ */
+ INIT(false) {
+
+ },
+ /**
+ * Once the session is established, wait for open message.
+ */
+ OPENWAIT(false) {
+ @Override
+ void processPcepMessage(PcepChannelHandler h, PcepMessage m) throws IOException, PcepParseException {
+
+ log.info("Message received in OPEN WAIT State");
+
+ //check for open message
+ if (m.getType() != PcepType.OPEN) {
+ // When the message type is not open message increment the wrong packet statistics
+ h.processUnknownMsg();
+ log.debug("Message is not OPEN message");
+ } else {
+
+ h.pcepPacketStats.addInPacket();
+ PcepOpenMsg pOpenmsg = (PcepOpenMsg) m;
+ //Do Capability negotiation.
+ h.capabilityNegotiation(pOpenmsg);
+ log.debug("Sending handshake OPEN message");
+ h.sessionId = pOpenmsg.getPcepOpenObject().getSessionId();
+ h.pcepVersion = pOpenmsg.getPcepOpenObject().getVersion();
+
+ //setting keepalive and deadTimer
+ byte yKeepalive = pOpenmsg.getPcepOpenObject().getKeepAliveTime();
+ byte yDeadTimer = pOpenmsg.getPcepOpenObject().getDeadTime();
+ h.keepAliveTime = yKeepalive;
+ if (yKeepalive < yDeadTimer) {
+ h.deadTime = yDeadTimer;
+ } else {
+ if (DEADTIMER_MAXIMUM_VALUE > (yKeepalive * KEEPALIVE_MULTIPLE_FOR_DEADTIMER)) {
+ h.deadTime = (byte) (yKeepalive * KEEPALIVE_MULTIPLE_FOR_DEADTIMER);
+ } else {
+ h.deadTime = DEADTIMER_MAXIMUM_VALUE;
+ }
+ }
+
+ /*
+ * 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();
+ if (optionalTlvs != null) {
+ for (PcepValueType optionalTlv : optionalTlvs) {
+ if (optionalTlv instanceof NodeAttributesTlv) {
+ List<PcepValueType> subTlvs = ((NodeAttributesTlv) optionalTlv)
+ .getllNodeAttributesSubTLVs();
+ if (subTlvs == null) {
+ break;
+ }
+ for (PcepValueType subTlv : subTlvs) {
+ if (subTlv instanceof IPv4RouterIdOfLocalNodeSubTlv) {
+ h.thispccId = PccId.pccId(IpAddress
+ .valueOf(((IPv4RouterIdOfLocalNodeSubTlv) subTlv).getInt()));
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ if (h.thispccId == null) {
+ final SocketAddress address = h.channel.getRemoteAddress();
+ if (!(address instanceof InetSocketAddress)) {
+ throw new IOException("Invalid client connection. Pcc is indentifed based on IP");
+ }
+
+ final InetSocketAddress inetAddress = (InetSocketAddress) address;
+ h.thispccId = PccId.pccId(IpAddress.valueOf(inetAddress.getAddress()));
+ }
+
+ h.sendHandshakeOpenMessage();
+ h.pcepPacketStats.addOutPacket();
+ h.setState(KEEPWAIT);
+ h.controller.peerStatus(h.peerAddr.toString(), PcepCfg.State.KEEPWAIT.toString(), h.sessionId);
+ }
+ }
+ },
+ /**
+ * Once the open messages are exchanged, wait for keep alive message.
+ */
+ KEEPWAIT(false) {
+ @Override
+ void processPcepMessage(PcepChannelHandler h, PcepMessage m) throws IOException, PcepParseException {
+ log.info("Message received in KEEPWAIT state");
+ //check for keep alive message
+ if (m.getType() != PcepType.KEEP_ALIVE) {
+ // When the message type is not keep alive message increment the wrong packet statistics
+ h.processUnknownMsg();
+ log.error("Message is not KEEPALIVE message");
+ } else {
+ // Set the client connected status
+ h.pcepPacketStats.addInPacket();
+ log.debug("sending keep alive message in KEEPWAIT state");
+ h.pc = h.controller.getPcepClientInstance(h.thispccId, h.sessionId, h.pcepVersion,
+ h.pcepPacketStats);
+ //Get pc instance and set capabilities
+ h.pc.setCapability(h.capability);
+
+ // Initilialize DB sync status.
+ h.pc.setLspDbSyncStatus(NOT_SYNCED);
+ h.pc.setLabelDbSyncStatus(NOT_SYNCED);
+
+ // set the status of pcc as connected
+ h.pc.setConnected(true);
+ h.pc.setChannel(h.channel);
+
+ // set any other specific parameters to the pcc
+ h.pc.setPcVersion(h.pcepVersion);
+ h.pc.setPcSessionId(h.sessionId);
+ h.pc.setPcKeepAliveTime(h.keepAliveTime);
+ h.pc.setPcDeadTime(h.deadTime);
+ int keepAliveTimer = h.keepAliveTime & BYTE_MASK;
+ int deadTimer = h.deadTime & BYTE_MASK;
+ if (0 == h.keepAliveTime) {
+ h.deadTime = 0;
+ }
+ // handle keep alive and dead time
+ if (keepAliveTimer != PcepPipelineFactory.DEFAULT_KEEP_ALIVE_TIME
+ || deadTimer != PcepPipelineFactory.DEFAULT_DEAD_TIME) {
+
+ h.channel.getPipeline().replace("idle", "idle",
+ new IdleStateHandler(PcepPipelineFactory.TIMER, deadTimer, keepAliveTimer, 0));
+ }
+ log.debug("Dead timer : " + deadTimer);
+ log.debug("Keep alive time : " + keepAliveTimer);
+
+ //set the state handshake completion.
+
+ h.sendKeepAliveMessage();
+ h.pcepPacketStats.addOutPacket();
+ h.setHandshakeComplete(true);
+
+ if (!h.pc.connectClient()) {
+ disconnectDuplicate(h);
+ } else {
+ h.setState(ESTABLISHED);
+ h.controller.peerStatus(h.peerAddr.toString(), PcepCfg.State.ESTABLISHED.toString(), h.sessionId);
+ //Session is established, add a network configuration with LSR id and device capabilities.
+ h.addNode();
+ }
+ }
+ }
+ },
+ /**
+ * Once the keep alive messages are exchanged, the state is established.
+ */
+ ESTABLISHED(true) {
+ @Override
+ void processPcepMessage(PcepChannelHandler h, PcepMessage m) throws IOException, PcepParseException {
+
+ //h.channel.getPipeline().remove("waittimeout");
+ log.debug("Message received in established state " + m.getType());
+ //dispatch the message
+ h.dispatchMessage(m);
+ }
+ };
+ private boolean handshakeComplete;
+
+ ChannelState(boolean handshakeComplete) {
+ this.handshakeComplete = handshakeComplete;
+ }
+
+ void processPcepMessage(PcepChannelHandler h, PcepMessage m) throws IOException, PcepParseException {
+ // do nothing
+ }
+
+ /**
+ * Is this a state in which the handshake has completed.
+ *
+ * @return true if the handshake is complete
+ */
+ public boolean isHandshakeComplete() {
+ return this.handshakeComplete;
+ }
+
+ /**
+ * Sets handshake complete status.
+ *
+ * @param handshakeComplete status of handshake
+ */
+ public void setHandshakeComplete(boolean handshakeComplete) {
+ this.handshakeComplete = handshakeComplete;
+ }
+
+ protected void disconnectDuplicate(PcepChannelHandler h) {
+ log.error("Duplicated Pcc IP or incompleted cleanup - " + "disconnecting channel {}",
+ h.getClientInfoString());
+ h.duplicatePccIdFound = Boolean.TRUE;
+ h.channel.disconnect();
+ }
+
+ }
}
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 999dd40..8ffc707 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
@@ -15,17 +15,18 @@
*/
package org.onosproject.pcep.controller.impl;
-import java.util.Arrays;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.List;
+import java.util.LinkedList;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.HashMap;
import java.util.Collection;
import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
import java.util.ListIterator;
-import java.util.Map;
-import java.util.Set;
+import java.util.Arrays;
+import java.util.Iterator;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
@@ -185,6 +186,7 @@
private DeviceListener deviceListener = new InternalDeviceListener();
private LinkListener linkListener = new InternalLinkListener();
private InternalConfigListener cfgListener = new InternalConfigListener();
+ private Map<Integer, Integer> pcepErrorMsg = new TreeMap<>();
@Activate
public void activate() {
@@ -220,6 +222,39 @@
}
@Override
+ public void peerErrorMsg(String peerId, Integer errorType, Integer errValue) {
+ if (peerId == null) {
+ pcepErrorMsg.put(errorType, errValue);
+ } else {
+ if (pcepErrorMsg.size() > 10) {
+ pcepErrorMsg.clear();
+ }
+ pcepErrorMsg.put(errorType, errValue);
+ }
+ }
+
+ @Override
+ public Map<String, List<String>> getPcepExceptions() {
+ return this.ctrl.exceptionsMap();
+ }
+
+ @Override
+ public Map<Integer, Integer> getPcepErrorMsg() {
+ return pcepErrorMsg;
+ }
+
+
+ @Override
+ public Map<String, String> getPcepSessionMap() {
+ return this.ctrl.mapPeer();
+ }
+
+ @Override
+ public Map<String, Byte> getPcepSessionIdMap() {
+ return this.ctrl.mapSession();
+ }
+
+ @Override
public Collection<PcepClient> getClients() {
return connectedClients.values();
}
@@ -879,7 +914,7 @@
connectedClients.remove(pccId);
for (PcepClientListener l : pcepClientListener) {
- log.warn("removal for {}", pccId.toString());
+ log.warn("Removal for {}", pccId.toString());
l.clientDisconnected(pccId);
}
}
diff --git a/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepConfig.java b/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepConfig.java
new file mode 100644
index 0000000..2c8c162
--- /dev/null
+++ b/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepConfig.java
@@ -0,0 +1,44 @@
+/*
+ * 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.impl;
+
+import org.onosproject.pcep.controller.PccId;
+import org.onosproject.pcep.controller.PcepCfg;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.TreeMap;
+
+
+public class PcepConfig implements PcepCfg {
+
+ protected static final Logger log = LoggerFactory.getLogger(PcepConfig.class);
+
+ private State state = State.INIT;
+ private PccId pccId;
+ private TreeMap<String, PcepCfg> bgpPeerTree = new TreeMap<>();
+
+ @Override
+ public State getState() {
+ return state;
+ }
+
+ @Override
+ public void setState(State state) {
+ this.state = state;
+ }
+
+}