diff options
Diffstat (limited to 'framework/src/onos/bgp/ctl')
7 files changed, 513 insertions, 442 deletions
diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPChannelHandler.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPChannelHandler.java index c17736ed..f21c311c 100755 --- a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPChannelHandler.java +++ b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPChannelHandler.java @@ -17,13 +17,19 @@ package org.onosproject.bgp.controller.impl; import java.io.IOException; +import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.SocketAddress; +import java.net.UnknownHostException; import java.nio.channels.ClosedChannelException; -import java.util.Date; +import java.util.Collections; import java.util.List; +import java.util.LinkedList; +import java.util.ListIterator; import java.util.concurrent.RejectedExecutionException; +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.ChannelStateEvent; @@ -32,17 +38,24 @@ import org.jboss.netty.channel.MessageEvent; import org.jboss.netty.handler.timeout.IdleStateAwareChannelHandler; import org.jboss.netty.handler.timeout.ReadTimeoutException; import org.jboss.netty.handler.timeout.ReadTimeoutHandler; +import org.onlab.packet.Ip4Address; import org.onlab.packet.IpAddress; import org.onosproject.bgp.controller.BGPCfg; +import org.onosproject.bgp.controller.BGPController; import org.onosproject.bgp.controller.BGPId; import org.onosproject.bgp.controller.BGPPeer; import org.onosproject.bgp.controller.BGPPeerCfg; -import org.onosproject.bgp.controller.impl.BGPControllerImpl.BGPPeerManager; +import org.onosproject.bgp.controller.impl.BGPControllerImpl.BGPPeerManagerImpl; import org.onosproject.bgpio.exceptions.BGPParseException; +import org.onosproject.bgpio.protocol.BGPFactory; import org.onosproject.bgpio.protocol.BGPMessage; -//import org.onosproject.bgpio.protocol.BGPOpenMsg; +import org.onosproject.bgpio.protocol.BGPOpenMsg; import org.onosproject.bgpio.protocol.BGPType; import org.onosproject.bgpio.protocol.BGPVersion; +import org.onosproject.bgpio.types.BGPErrorType; +import org.onosproject.bgpio.types.BGPValueType; +import org.onosproject.bgpio.types.FourOctetAsNumCapabilityTlv; +import org.onosproject.bgpio.types.MultiProtocolExtnCapabilityTlv; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -52,18 +65,25 @@ import org.slf4j.LoggerFactory; class BGPChannelHandler extends IdleStateAwareChannelHandler { private static final Logger log = LoggerFactory.getLogger(BGPChannelHandler.class); - + static final int BGP_MIN_HOLDTIME = 3; static final int BGP_MAX_KEEPALIVE_INTERVAL = 3; private BGPPeer bgpPeer; private BGPId thisbgpId; - Channel channel; + private Channel channel; private BGPKeepAliveTimer keepAliveTimer = null; private short peerHoldTime = 0; private short negotiatedHoldTime = 0; - private short peerAsNum; + private long peerAsNum; private int peerIdentifier; private BGPPacketStatsImpl bgpPacketStats; static final int MAX_WRONG_COUNT_PACKET = 5; + static final byte MULTI_PROTOCOL_EXTN_CAPA_TYPE = 1; + static final byte FOUR_OCTET_AS_NUM_CAPA_TYPE = 65; + static final int AS_TRANS = 23456; + static final int MAX_AS2_NUM = 65535; + static final short AFI = 16388; + static final byte RES = 0; + static final byte SAFI = 71; // State needs to be volatile because the HandshakeTimeoutHandler // needs to check if the handshake is complete @@ -72,13 +92,17 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { // When a bgp peer with a ip addresss is found (i.e we already have a // connected peer with the same ip), the new peer is immediately // disconnected. At that point netty callsback channelDisconnected() which - // proceeds to cleaup peer state - we need to ensure that it does not cleanup + // proceeds to cleaup peer state - we need to ensure that it does not + // cleanup // peer state for the older (still connected) peer private volatile Boolean duplicateBGPIdFound; // Indicates the bgp version used by this bgp peer protected BGPVersion bgpVersion; - private BGPControllerImpl bgpControllerImpl; - private BGPPeerManager peerManager; + private BGPController bgpController; + protected BGPFactory factory4; + private boolean isIbgpSession; + private BgpSessionInfoImpl sessionInfo; + private BGPPeerManagerImpl peerManager; private InetSocketAddress inetAddress; private IpAddress ipAddress; private SocketAddress address; @@ -88,15 +112,16 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { /** * Create a new unconnected BGPChannelHandler. * - * @param bgpCtrlImpl bgp controller implementation object + * @param bgpController bgp controller */ - BGPChannelHandler(BGPControllerImpl bgpCtrlImpl) { - this.bgpControllerImpl = bgpCtrlImpl; - this.peerManager = bgpCtrlImpl.getPeerManager(); + BGPChannelHandler(BGPController bgpController) { + this.bgpController = bgpController; + this.peerManager = (BGPPeerManagerImpl) bgpController.peerManager(); this.state = ChannelState.IDLE; + this.factory4 = Controller.getBGPMessageFactory4(); this.duplicateBGPIdFound = Boolean.FALSE; this.bgpPacketStats = new BGPPacketStatsImpl(); - this.bgpconfig = bgpCtrlImpl.getConfig(); + this.bgpconfig = bgpController.getConfig(); } // To disconnect peer session. @@ -127,17 +152,19 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { // check for OPEN message if (m.getType() != BGPType.OPEN) { // When the message type is not keep alive message increment the wrong packet statistics - h.processUnknownMsg(); + h.processUnknownMsg(BGPErrorType.FINITE_STATE_MACHINE_ERROR, + BGPErrorType.RECEIVE_UNEXPECTED_MESSAGE_IN_OPENSENT_STATE, m.getType() + .getType()); log.debug("Message is not OPEN message"); } else { log.debug("Sending keep alive message in OPENSENT state"); h.bgpPacketStats.addInPacket(); - // TODO: initialize openmessage BGPOpenMsg pOpenmsg = (BGPOpenMsg) m; - // TODO: initialize identifier from open messgae h.peerIdentifier = pOpenmsg.getBgpId(); + BGPOpenMsg pOpenmsg = (BGPOpenMsg) m; + h.peerIdentifier = pOpenmsg.getBgpId(); // validate capabilities and open msg - if (h.openMsgValidation(h)) { + if (h.openMsgValidation(h, pOpenmsg)) { log.debug("Sending handshake OPEN message"); /* @@ -145,7 +172,7 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { * value of the Hold Timer by using the smaller of its configured Hold Time and the Hold Time * received in the OPEN message */ - // TODO: initialize holdtime from open message h.peerHoldTime = pOpenmsg.getHoldTime(); + h.peerHoldTime = pOpenmsg.getHoldTime(); if (h.peerHoldTime < h.bgpconfig.getHoldTime()) { h.channel.getPipeline().replace("holdTime", "holdTime", @@ -155,7 +182,8 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { log.info("Hold Time : " + h.peerHoldTime); - // TODO: get AS number for open message update AS number + // update AS number + h.peerAsNum = pOpenmsg.getAsNumber(); } // Send keepalive message to peer. @@ -175,15 +203,17 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { // check for open message if (m.getType() != BGPType.OPEN) { // When the message type is not open message increment the wrong packet statistics - h.processUnknownMsg(); + h.processUnknownMsg(BGPErrorType.FINITE_STATE_MACHINE_ERROR, BGPErrorType.UNSPECIFIED_ERROR, m + .getType().getType()); log.debug("Message is not OPEN message"); } else { h.bgpPacketStats.addInPacket(); - // TODO: initialize open message BGPOpenMsg pOpenmsg = (BGPOpenMsg) m; + BGPOpenMsg pOpenmsg = (BGPOpenMsg) m; + h.peerIdentifier = pOpenmsg.getBgpId(); // Validate open message - if (h.openMsgValidation(h)) { + if (h.openMsgValidation(h, pOpenmsg)) { log.debug("Sending handshake OPEN message"); /* @@ -191,7 +221,7 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { * value of the Hold Timer by using the smaller of its configured Hold Time and the Hold Time * received in the OPEN message */ - // TODO: get hold time from open message h.peerHoldTime = pOpenmsg.getHoldTime(); + h.peerHoldTime = pOpenmsg.getHoldTime(); if (h.peerHoldTime < h.bgpconfig.getHoldTime()) { h.channel.getPipeline().replace("holdTime", "holdTime", @@ -201,7 +231,8 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { log.debug("Hold Time : " + h.peerHoldTime); - //TODO: update AS number form open messsage update AS number + // update AS number + h.peerAsNum = pOpenmsg.getAsNumber(); h.sendHandshakeOpenMessage(); h.bgpPacketStats.addOutPacket(); @@ -218,7 +249,9 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { // check for keep alive message if (m.getType() != BGPType.KEEP_ALIVE) { // When the message type is not keep alive message handle the wrong packet - h.processUnknownMsg(); + h.processUnknownMsg(BGPErrorType.FINITE_STATE_MACHINE_ERROR, + BGPErrorType.RECEIVE_UNEXPECTED_MESSAGE_IN_OPENCONFIRM_STATE, m.getType() + .getType()); log.debug("Message is not KEEPALIVE message"); } else { @@ -229,30 +262,28 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { final InetSocketAddress inetAddress = (InetSocketAddress) h.address; h.thisbgpId = BGPId.bgpId(IpAddress.valueOf(inetAddress.getAddress())); - h.bgpPeer = h.peerManager.getBGPPeerInstance(h.thisbgpId, h.bgpVersion, h.bgpPacketStats); - // set the status fo bgp as connected + // set session parameters + h.negotiatedHoldTime = (h.peerHoldTime < h.bgpconfig.getHoldTime()) ? h.peerHoldTime + : h.bgpconfig.getHoldTime(); + h.sessionInfo = new BgpSessionInfoImpl(h.thisbgpId, h.bgpVersion, h.peerAsNum, h.peerHoldTime, + h.peerIdentifier, h.negotiatedHoldTime, h.isIbgpSession); + + h.bgpPeer = h.peerManager.getBGPPeerInstance(h.bgpController, h.sessionInfo, h.bgpPacketStats); + // set the status of bgp as connected h.bgpPeer.setConnected(true); h.bgpPeer.setChannel(h.channel); - // set specific parameters to bgp peer - h.bgpPeer.setBgpPeerVersion(h.bgpVersion); - h.bgpPeer.setBgpPeerASNum(h.peerAsNum); - h.bgpPeer.setBgpPeerHoldTime(h.peerHoldTime); - h.bgpPeer.setBgpPeerIdentifier(h.peerIdentifier); - - h.negotiatedHoldTime = (h.peerHoldTime < h.bgpconfig.getHoldTime()) ? h.peerHoldTime : h.bgpconfig - .getHoldTime(); - h.bgpPeer.setNegotiatedHoldTime(h.negotiatedHoldTime); /* * RFC 4271, When an OPEN message is received, sends a KEEPALIVE message, If the negotiated hold * time value is zero, then the HoldTimer and KeepaliveTimer are not started. A reasonable maximum * time between KEEPALIVE messages would be one third of the Hold Time interval. */ - h.sendKeepAliveMessage(); if (h.negotiatedHoldTime != 0) { - h.keepAliveTimer - = new BGPKeepAliveTimer(h, (h.negotiatedHoldTime / BGP_MAX_KEEPALIVE_INTERVAL)); + h.keepAliveTimer = new BGPKeepAliveTimer(h, + (h.negotiatedHoldTime / BGP_MAX_KEEPALIVE_INTERVAL)); + } else { + h.sendKeepAliveMessage(); } h.bgpPacketStats.addOutPacket(); @@ -349,8 +380,7 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { } inetAddress = (InetSocketAddress) address; - ipAddress = IpAddress.valueOf(inetAddress.getAddress()); - peerAddr = ipAddress.toString(); + peerAddr = IpAddress.valueOf(inetAddress.getAddress()).toString(); // if peer is not configured disconnect session if (!bgpconfig.isPeerConfigured(peerAddr)) { @@ -360,7 +390,7 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { } // if connection is already established close channel - if (peerManager.isPeerConnected(peerAddr)) { + if (peerManager.isPeerConnected(BGPId.bgpId(IpAddress.valueOf(peerAddr)))) { log.debug("Duplicate connection received, peer {}", peerAddr); channel.close(); return; @@ -392,8 +422,7 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { } inetAddress = (InetSocketAddress) address; - ipAddress = IpAddress.valueOf(inetAddress.getAddress()); - peerAddr = ipAddress.toString(); + peerAddr = IpAddress.valueOf(inetAddress.getAddress()).toString(); if (thisbgpId != null) { if (!duplicateBGPIdFound) { @@ -432,14 +461,14 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { if ((ChannelState.OPENWAIT == state) || (ChannelState.OPENSENT == state)) { // When ReadTimeout timer is expired in OPENWAIT/OPENSENT state, it is considered - // TODO: Send notification + sendNotification(BGPErrorType.HOLD_TIMER_EXPIRED, (byte) 0, null); channel.close(); state = ChannelState.IDLE; return; } else if (ChannelState.OPENCONFIRM == state) { // When ReadTimeout timer is expired in OPENCONFIRM state. - // TODO: Send Notification + sendNotification(BGPErrorType.HOLD_TIMER_EXPIRED, (byte) 0, null); channel.close(); state = ChannelState.IDLE; return; @@ -454,8 +483,17 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { } channel.close(); } else if (e.getCause() instanceof BGPParseException) { - // TODO: SEND NOTIFICATION - log.debug("BGP Parse Exception: ", e.getCause()); + byte[] data = new byte[] {}; + BGPParseException errMsg = (BGPParseException) e.getCause(); + byte errorCode = errMsg.getErrorCode(); + byte errorSubCode = errMsg.getErrorSubCode(); + ChannelBuffer tempCb = errMsg.getData(); + if (tempCb != null) { + int dataLength = tempCb.capacity(); + data = new byte[dataLength]; + tempCb.readBytes(data, 0, dataLength); + } + sendNotification(errorCode, errorSubCode, data); } else if (e.getCause() instanceof RejectedExecutionException) { log.warn("Could not process message: queue full"); } else { @@ -507,11 +545,12 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { /** * To handle the BGP message. * - * @param m BGP message + * @param m bgp message + * @throws BGPParseException throw exception */ private void dispatchMessage(BGPMessage m) throws BGPParseException { bgpPacketStats.addInPacket(); - bgpControllerImpl.processBGPPacket(thisbgpId, m); + bgpController.processBGPPacket(thisbgpId, m); } /** @@ -557,14 +596,39 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { /** * Send handshake open message to the peer. * - * @throws IOException ,BGPParseException + * @throws IOException, BGPParseException */ private void sendHandshakeOpenMessage() throws IOException, BGPParseException { - // TODO: send open message. + int bgpId; + + bgpId = Ip4Address.valueOf(bgpconfig.getRouterId()).toInt(); + BGPMessage msg = factory4.openMessageBuilder().setAsNumber((short) bgpconfig.getAsNumber()) + .setHoldTime(bgpconfig.getHoldTime()).setBgpId(bgpId) + .setLsCapabilityTlv(bgpconfig.getLsCapability()) + .setLargeAsCapabilityTlv(bgpconfig.getLargeASCapability()) + .build(); + log.debug("Sending open message to {}", channel.getRemoteAddress()); + channel.write(Collections.singletonList(msg)); } /** + * Send notification message to peer. + * + * @param errorCode error code send in notification + * @param errorSubCode sub error code send in notification + * @param data data to send in notification + * @throws IOException, BGPParseException while building message + */ + private void sendNotification(byte errorCode, byte errorSubCode, byte[] data) + throws IOException, BGPParseException { + BGPMessage msg = factory4.notificationMessageBuilder().setErrorCode(errorCode).setErrorSubCode(errorSubCode) + .setData(data).build(); + log.debug("Sending notification message to {}", channel.getRemoteAddress()); + channel.write(Collections.singletonList(msg)); + } + + /** * Send keep alive message. * * @throws IOException when channel is disconnected @@ -572,60 +636,220 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { */ synchronized void sendKeepAliveMessage() throws IOException, BGPParseException { - // TODO: send keep alive message. + BGPMessage msg = factory4.keepaliveMessageBuilder().build(); + log.debug("Sending keepalive message to {}", channel.getRemoteAddress()); + channel.write(Collections.singletonList(msg)); } /** - * Send notification and close channel with peer. + * Process unknown BGP message received. + * + * @param errorCode error code + * @param errorSubCode error sub code + * @param data message type + * @throws BGPParseException while processing error messsage + * @throws IOException while processing error message */ - private void sendErrNotificationAndCloseChannel() { - // TODO: send notification + public void processUnknownMsg(byte errorCode, byte errorSubCode, byte data) throws BGPParseException, IOException { + log.debug("UNKNOWN message received"); + byte[] byteArray = new byte[1]; + byteArray[0] = data; + sendNotification(errorCode, errorSubCode, byteArray); channel.close(); } /** - * Process unknown BGP message received. + * BGP open message validation. * - * @throws BGPParseException when received invalid message + * @param h channel handler + * @param openMsg open message + * @return true if valid message, otherwise false + * @throws BGPParseException throw exception */ - public void processUnknownMsg() throws BGPParseException { - log.debug("UNKNOWN message received"); - Date now = null; - if (bgpPacketStats.wrongPacketCount() == 0) { - now = new Date(); - bgpPacketStats.setTime(now.getTime()); - bgpPacketStats.addWrongPacket(); - sendErrNotificationAndCloseChannel(); + public boolean openMsgValidation(BGPChannelHandler h, BGPOpenMsg openMsg) throws BGPParseException { + boolean result; + + // Validate BGP ID + result = bgpIdValidation(openMsg); + if (!result) { + throw new BGPParseException(BGPErrorType.OPEN_MESSAGE_ERROR, BGPErrorType.BAD_BGP_IDENTIFIER, null); + } + + // Validate AS number + result = asNumberValidation(h, openMsg); + if (!result) { + throw new BGPParseException(BGPErrorType.OPEN_MESSAGE_ERROR, BGPErrorType.BAD_PEER_AS, null); + } + + // Validate hold timer + if ((openMsg.getHoldTime() != 0) && (openMsg.getHoldTime() < BGP_MIN_HOLDTIME)) { + throw new BGPParseException(BGPErrorType.OPEN_MESSAGE_ERROR, BGPErrorType.UNACCEPTABLE_HOLD_TIME, null); + } + + // Validate capabilities + result = capabilityValidation(h, openMsg); + return result; + } + + /** + * Capability Validation. + * + * @param h channel handler + * @param openmsg open message + * @return success or failure + * @throws BGPParseException + */ + private boolean capabilityValidation(BGPChannelHandler h, BGPOpenMsg openmsg) throws BGPParseException { + log.debug("capabilityValidation"); + + boolean isMultiProtocolcapabilityExists = false; + boolean isFourOctetCapabilityExits = false; + int capAsNum = 0; + + List<BGPValueType> capabilityTlv = openmsg.getCapabilityTlv(); + ListIterator<BGPValueType> listIterator = capabilityTlv.listIterator(); + List<BGPValueType> unSupportedCapabilityTlv = new LinkedList<>(); + ListIterator<BGPValueType> unSupportedCaplistIterator = unSupportedCapabilityTlv.listIterator(); + BGPValueType tempTlv; + boolean isLargeAsCapabilityCfg = h.bgpconfig.getLargeASCapability(); + boolean isLsCapabilityCfg = h.bgpconfig.getLsCapability(); + + while (listIterator.hasNext()) { + BGPValueType tlv = listIterator.next(); + if (tlv.getType() == MULTI_PROTOCOL_EXTN_CAPA_TYPE) { + isMultiProtocolcapabilityExists = true; + } + if (tlv.getType() == FOUR_OCTET_AS_NUM_CAPA_TYPE) { + isFourOctetCapabilityExits = true; + capAsNum = ((FourOctetAsNumCapabilityTlv) tlv).getInt(); + } } - if (bgpPacketStats.wrongPacketCount() > 1) { - Date lastest = new Date(); - bgpPacketStats.addWrongPacket(); - // converting to seconds - if (((lastest.getTime() - bgpPacketStats.getTime()) / 1000) > 60) { - now = lastest; - bgpPacketStats.setTime(now.getTime()); - bgpPacketStats.resetWrongPacket(); - bgpPacketStats.addWrongPacket(); - } else if (((int) (lastest.getTime() - now.getTime()) / 1000) < 60) { - if (MAX_WRONG_COUNT_PACKET <= bgpPacketStats.wrongPacketCount()) { - // reset once wrong packet count reaches MAX_WRONG_COUNT_PACKET - bgpPacketStats.resetWrongPacket(); - // max wrong packets received send error message and close the session - sendErrNotificationAndCloseChannel(); + + if (isFourOctetCapabilityExits) { + if (capAsNum > MAX_AS2_NUM) { + if (openmsg.getAsNumber() != AS_TRANS) { + throw new BGPParseException(BGPErrorType.OPEN_MESSAGE_ERROR, BGPErrorType.BAD_PEER_AS, null); + } + } else { + if (capAsNum != openmsg.getAsNumber()) { + throw new BGPParseException(BGPErrorType.OPEN_MESSAGE_ERROR, BGPErrorType.BAD_PEER_AS, null); } } } + + if ((isLsCapabilityCfg)) { + if (!isMultiProtocolcapabilityExists) { + tempTlv = new MultiProtocolExtnCapabilityTlv(AFI, RES, SAFI); + unSupportedCapabilityTlv.add(tempTlv); + } + } + + if ((isLargeAsCapabilityCfg)) { + if (!isFourOctetCapabilityExits) { + tempTlv = new FourOctetAsNumCapabilityTlv(h.bgpconfig.getAsNumber()); + unSupportedCapabilityTlv.add(tempTlv); + } + } + + if (unSupportedCaplistIterator.hasNext()) { + ChannelBuffer buffer = ChannelBuffers.dynamicBuffer(); + while (unSupportedCaplistIterator.hasNext()) { + BGPValueType tlv = unSupportedCaplistIterator.next(); + tlv.write(buffer); + } + throw new BGPParseException(BGPErrorType.OPEN_MESSAGE_ERROR, + BGPErrorType.UNSUPPORTED_CAPABILITY, buffer); + } else { + return true; + } } /** - * Open message validation. + * AS Number Validation. * - * @param h channel handler - * @return true if validation succeed, otherwise false - * @throws BGPParseException when received invalid message + * @param h channel Handler + * @param openMsg open message + * @return true or false */ - public boolean openMsgValidation(BGPChannelHandler h) throws BGPParseException { - // TODO: Open message validation. + private boolean asNumberValidation(BGPChannelHandler h, BGPOpenMsg openMsg) { + log.debug("AS Num validation"); + + int capAsNum = 0; + boolean isFourOctetCapabilityExits = false; + + BGPPeerCfg peerCfg = h.bgpconfig.displayPeers(peerAddr); + List<BGPValueType> capabilityTlv = openMsg.getCapabilityTlv(); + ListIterator<BGPValueType> listIterator = capabilityTlv.listIterator(); + + while (listIterator.hasNext()) { + BGPValueType tlv = listIterator.next(); + if (tlv.getType() == FOUR_OCTET_AS_NUM_CAPA_TYPE) { + isFourOctetCapabilityExits = true; + capAsNum = ((FourOctetAsNumCapabilityTlv) tlv).getInt(); + } + } + + if (peerCfg.getAsNumber() > MAX_AS2_NUM) { + if (openMsg.getAsNumber() != AS_TRANS) { + return false; + } + + if (!isFourOctetCapabilityExits) { + return false; + } + + if (peerCfg.getAsNumber() != capAsNum) { + return false; + } + + isIbgpSession = peerCfg.getIsIBgp(); + if (isIbgpSession) { + // IBGP - AS number should be same for Peer and local if it is IBGP + if (h.bgpconfig.getAsNumber() != capAsNum) { + return false; + } + } + } else { + + if (openMsg.getAsNumber() != peerCfg.getAsNumber()) { + return false; + } + + if (isFourOctetCapabilityExits) { + if (capAsNum != peerCfg.getAsNumber()) { + return false; + } + } + + isIbgpSession = peerCfg.getIsIBgp(); + if (isIbgpSession) { + // IBGP - AS number should be same for Peer and local if it is IBGP + if (openMsg.getAsNumber() != h.bgpconfig.getAsNumber()) { + return false; + } + } + } + return true; + } + + /** + * Validates BGP ID. + * + * @param openMsg open message + * @return true or false + */ + private boolean bgpIdValidation(BGPOpenMsg openMsg) { + String openMsgBgpId = Ip4Address.valueOf(openMsg.getBgpId()).toString(); + + InetAddress ipAddress; + try { + ipAddress = InetAddress.getByName(openMsgBgpId); + if (ipAddress.isMulticastAddress()) { + return false; + } + } catch (UnknownHostException e) { + log.debug("InetAddress convertion failed"); + } return true; } } diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPControllerImpl.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPControllerImpl.java index d8378e31..35c31ab7 100755 --- a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPControllerImpl.java +++ b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPControllerImpl.java @@ -16,25 +16,25 @@ package org.onosproject.bgp.controller.impl; -import static org.onlab.util.Tools.groupedThreads; - +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; +import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; + import org.apache.felix.scr.annotations.Activate; import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Deactivate; import org.apache.felix.scr.annotations.Service; -import org.onlab.packet.IpAddress; import org.onosproject.bgp.controller.BGPCfg; import org.onosproject.bgp.controller.BGPController; import org.onosproject.bgp.controller.BGPId; -import org.onosproject.bgp.controller.BGPPacketStats; import org.onosproject.bgp.controller.BGPPeer; +import org.onosproject.bgp.controller.BgpLinkListener; +import org.onosproject.bgp.controller.BgpNodeListener; +import org.onosproject.bgp.controller.BgpPeerManager; +import org.onosproject.bgpio.exceptions.BGPParseException; import org.onosproject.bgpio.protocol.BGPMessage; -import org.onosproject.bgpio.protocol.BGPVersion; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -44,16 +44,13 @@ public class BGPControllerImpl implements BGPController { private static final Logger log = LoggerFactory.getLogger(BGPControllerImpl.class); - private final ExecutorService executorMsgs = Executors.newFixedThreadPool(32, - groupedThreads("onos/bgp", - "event-stats-%d")); - - private final ExecutorService executorBarrier = Executors.newFixedThreadPool(4, - groupedThreads("onos/bgp", - "event-barrier-%d")); protected ConcurrentHashMap<BGPId, BGPPeer> connectedPeers = new ConcurrentHashMap<BGPId, BGPPeer>(); - protected BGPPeerManager peerManager = new BGPPeerManager(); + protected BGPPeerManagerImpl peerManager = new BGPPeerManagerImpl(); + + protected Set<BgpNodeListener> bgpNodeListener = new CopyOnWriteArraySet<>(); + protected Set<BgpLinkListener> bgpLinkListener = new CopyOnWriteArraySet<>(); + final Controller ctrl = new Controller(this); private BGPConfig bgpconfig = new BGPConfig(); @@ -83,12 +80,42 @@ public class BGPControllerImpl implements BGPController { } @Override + public void addListener(BgpNodeListener listener) { + this.bgpNodeListener.add(listener); + } + + @Override + public void removeListener(BgpNodeListener listener) { + this.bgpNodeListener.remove(listener); + } + + @Override + public Set<BgpNodeListener> listener() { + return bgpNodeListener; + } + + @Override + public void addLinkListener(BgpLinkListener listener) { + this.bgpLinkListener.add(listener); + } + + @Override + public void removeLinkListener(BgpLinkListener listener) { + this.bgpLinkListener.remove(listener); + } + + @Override + public Set<BgpLinkListener> linkListener() { + return bgpLinkListener; + } + + @Override public void writeMsg(BGPId bgpId, BGPMessage msg) { - // TODO: Send message + this.getPeer(bgpId).sendMessage(msg); } @Override - public void processBGPPacket(BGPId bgpId, BGPMessage msg) { + public void processBGPPacket(BGPId bgpId, BGPMessage msg) throws BGPParseException { switch (msg.getType()) { case OPEN: @@ -122,18 +149,12 @@ public class BGPControllerImpl implements BGPController { * Implementation of an BGP Peer which is responsible for keeping track of connected peers and the state in which * they are. */ - public class BGPPeerManager { + public class BGPPeerManagerImpl implements BgpPeerManager { - private final Logger log = LoggerFactory.getLogger(BGPPeerManager.class); + private final Logger log = LoggerFactory.getLogger(BGPPeerManagerImpl.class); private final Lock peerLock = new ReentrantLock(); - /** - * Add a BGP peer that has just connected to the system. - * - * @param bgpId the id of bgp peer to add - * @param bgpPeer the actual bgp peer object. - * @return true if added, false otherwise. - */ + @Override public boolean addConnectedPeer(BGPId bgpId, BGPPeer bgpPeer) { if (connectedPeers.get(bgpId) != null) { @@ -147,119 +168,49 @@ public class BGPControllerImpl implements BGPController { } } - /** - * Checks if the activation for this bgp peer is valid. - * - * @param bgpId the id of bgp peer to check - * @return true if valid, false otherwise - */ + @Override public boolean isPeerConnected(BGPId bgpId) { if (connectedPeers.get(bgpId) == null) { - this.log.error("Trying to activate peer but is not in " + "connected peer: bgpIp {}. Aborting ..", - bgpId.toString()); + this.log.error("Is peer connected: bgpIp {}.", bgpId.toString()); return false; } return true; } - /** - * Checks if the activation for this bgp peer is valid. - * - * @param routerid the routerid of bgp peer to check - * @return true if valid, false otherwise - */ - public boolean isPeerConnected(String routerid) { - - final BGPId bgpId; - bgpId = BGPId.bgpId(IpAddress.valueOf(routerid)); - - if (connectedPeers.get(bgpId) != null) { - this.log.info("Peer connection exist "); - return true; - } - this.log.info("Initiate connect request to " + "peer: bgpIp {}", bgpId.toString()); - - return false; - } - - /** - * Clear all state in controller peer maps for a bgp peer that has - * disconnected from the local controller. - * - * @param bgpId the id of bgp peer to remove. - */ + @Override public void removeConnectedPeer(BGPId bgpId) { connectedPeers.remove(bgpId); } - /** - * Clear all state in controller peer maps for a bgp peer that has - * disconnected from the local controller. - * - * @param routerid the router id of bgp peer to remove. - */ - public void removeConnectedPeer(String routerid) { - final BGPId bgpId; - - bgpId = BGPId.bgpId(IpAddress.valueOf(routerid)); - - connectedPeers.remove(bgpId); - } - - /** - * Gets bgp peer for connected peer map. - * - * @param routerid router id - * @return peer if available, null otherwise - */ - public BGPPeer getPeer(String routerid) { - final BGPId bgpId; - bgpId = BGPId.bgpId(IpAddress.valueOf(routerid)); - + @Override + public BGPPeer getPeer(BGPId bgpId) { return connectedPeers.get(bgpId); } /** - * Gets bgp peer instance. - * - * @param bgpId bgp identifier. - * @param pv bgp version. - * @param pktStats packet statistics. - * @return BGPPeer peer instance. - */ - public BGPPeer getBGPPeerInstance(BGPId bgpId, BGPVersion pv, BGPPacketStats pktStats) { - BGPPeer bgpPeer = new BGPPeerImpl(); - bgpPeer.init(bgpId, pv, pktStats); + * Gets bgp peer instance. + * + * @param bgpController controller instance. + * @param sessionInfo bgp session info. + * @param pktStats packet statistics. + * @return BGPPeer peer instance. + */ + public BGPPeer getBGPPeerInstance(BGPController bgpController, BgpSessionInfoImpl sessionInfo, + BGPPacketStatsImpl pktStats) { + BGPPeer bgpPeer = new BGPPeerImpl(bgpController, sessionInfo, pktStats); return bgpPeer; } } - /** - * Gets controller instance. - * - * @return Controller instance. - */ - public Controller getController() { - return ctrl; - } - - /** - * Gets connected peers. - * - * @return connectedPeers from connected Peers Map. - */ - public ConcurrentHashMap<BGPId, BGPPeer> getConnectedPeers() { + @Override + public ConcurrentHashMap<BGPId, BGPPeer> connectedPeers() { return connectedPeers; } - /** - * Gets peer manager. - * - * @return peerManager. - */ - public BGPPeerManager getPeerManager() { + @Override + public BGPPeerManagerImpl peerManager() { return peerManager; } @@ -269,7 +220,7 @@ public class BGPControllerImpl implements BGPController { } @Override - public int getBGPConnNumber() { + public int connectedPeerCount() { return connectedPeers.size(); } -}
\ No newline at end of file +} diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPeerConfig.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPeerConfig.java index 51b95a4b..14a68cf6 100755 --- a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPeerConfig.java +++ b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPeerConfig.java @@ -16,6 +16,7 @@ package org.onosproject.bgp.controller.impl; import org.onlab.packet.Ip4Address; +import org.onosproject.bgp.controller.BgpConnectPeer; import org.onosproject.bgp.controller.BGPPeerCfg; /** @@ -28,6 +29,7 @@ public class BGPPeerConfig implements BGPPeerCfg { private Ip4Address peerId = null; private State state; private boolean selfInitiated; + private BgpConnectPeer connectPeer; /** * Constructor to initialize the values. @@ -106,4 +108,14 @@ public class BGPPeerConfig implements BGPPeerCfg { public void setSelfInnitConnection(boolean selfInit) { this.selfInitiated = selfInit; } + + @Override + public BgpConnectPeer connectPeer() { + return this.connectPeer; + } + + @Override + public void setConnectPeer(BgpConnectPeer connectPeer) { + this.connectPeer = connectPeer; + } } diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPeerImpl.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPeerImpl.java index 212b24d3..45f74634 100755 --- a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPeerImpl.java +++ b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPeerImpl.java @@ -24,11 +24,12 @@ import java.util.concurrent.RejectedExecutionException; import org.jboss.netty.channel.Channel; import org.onlab.packet.IpAddress; -import org.onosproject.bgp.controller.BGPId; -import org.onosproject.bgp.controller.BGPPacketStats; +import org.onosproject.bgp.controller.BGPController; import org.onosproject.bgp.controller.BGPPeer; +import org.onosproject.bgp.controller.BgpSessionInfo; +import org.onosproject.bgpio.protocol.BGPFactories; +import org.onosproject.bgpio.protocol.BGPFactory; import org.onosproject.bgpio.protocol.BGPMessage; -import org.onosproject.bgpio.protocol.BGPVersion; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,19 +44,31 @@ public class BGPPeerImpl implements BGPPeer { private static final String SHUTDOWN_MSG = "Worker has already been shutdown"; + private BGPController bgpController; private Channel channel; protected String channelId; private boolean connected; protected boolean isHandShakeComplete = false; - public BGPSessionInfo sessionInfo; + private BgpSessionInfo sessionInfo; private BGPPacketStatsImpl pktStats; + @Override - public void init(BGPId bgpId, BGPVersion bgpVersion, BGPPacketStats pktStats) { - this.sessionInfo.setRemoteBgpId(bgpId); - this.sessionInfo.setRemoteBgpVersion(bgpVersion); - this.pktStats = (BGPPacketStatsImpl) pktStats; - this.sessionInfo = new BGPSessionInfo(); + public BgpSessionInfo sessionInfo() { + return sessionInfo; + } + + /** + * Initialize peer. + * + *@param bgpController controller instance + *@param sessionInfo bgp session info + *@param pktStats packet statistics + */ + public BGPPeerImpl(BGPController bgpController, BgpSessionInfo sessionInfo, BGPPacketStatsImpl pktStats) { + this.bgpController = bgpController; + this.sessionInfo = sessionInfo; + this.pktStats = pktStats; } // ************************ @@ -129,53 +142,9 @@ public class BGPPeerImpl implements BGPPeer { return channelId; } - // ************************ - // BGP Peer features related - // ************************ - - @Override - public final BGPId getBGPId() { - return this.sessionInfo.getRemoteBgpId(); - }; - - @Override - public final String getStringId() { - return this.sessionInfo.getRemoteBgpId().toString(); - } - - @Override - public final void setBgpPeerVersion(BGPVersion peerVersion) { - this.sessionInfo.setRemoteBgpVersion(peerVersion); - } - - @Override - public void setBgpPeerASNum(short peerASNum) { - this.sessionInfo.setRemoteBgpASNum(peerASNum); - } - - @Override - public void setBgpPeerHoldTime(short peerHoldTime) { - this.sessionInfo.setRemoteBgpHoldTime(peerHoldTime); - } - - @Override - public void setBgpPeerIdentifier(int peerIdentifier) { - this.sessionInfo.setRemoteBgpIdentifier(peerIdentifier); - } - - @Override - public int getBgpPeerIdentifier() { - return this.sessionInfo.getRemoteBgpIdentifier(); - } - - @Override - public int getNegotiatedHoldTime() { - return this.sessionInfo.getNegotiatedholdTime(); - } - @Override - public void setNegotiatedHoldTime(short negotiatedHoldTime) { - this.sessionInfo.setNegotiatedholdTime(negotiatedHoldTime); + public BGPFactory factory() { + return BGPFactories.getFactory(sessionInfo.remoteBgpVersion()); } @Override @@ -185,7 +154,8 @@ public class BGPPeerImpl implements BGPPeer { @Override public String toString() { - return MoreObjects.toStringHelper(getClass()).omitNullValues().add("channel", channelId()) - .add("bgpId", getBGPId()).toString(); + return MoreObjects.toStringHelper(getClass()).omitNullValues() + .add("channel", channelId()) + .add("bgpId", sessionInfo().remoteBgpId()).toString(); } } diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPipelineFactory.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPipelineFactory.java index b2ca5077..e6f09f20 100755 --- a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPipelineFactory.java +++ b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPipelineFactory.java @@ -23,6 +23,7 @@ import org.jboss.netty.handler.timeout.ReadTimeoutHandler; import org.jboss.netty.util.ExternalResourceReleasable; import org.jboss.netty.util.HashedWheelTimer; import org.jboss.netty.util.Timer; +import org.onosproject.bgp.controller.BGPController; /** * Creates a ChannelPipeline for a server-side bgp channel. @@ -32,30 +33,36 @@ public class BGPPipelineFactory static final Timer TIMER = new HashedWheelTimer(); protected ReadTimeoutHandler readTimeoutHandler; - BGPControllerImpl bgpCtrlImpl; + private boolean isBgpServ; + private BGPController bgpController; /** * Constructor to initialize the values. * - * @param ctrlImpl parent ctrlImpl - * @param isServBgp if it is a server or not + * @param bgpController parent controller + * @param isBgpServ if it is a server or remote peer */ - public BGPPipelineFactory(BGPControllerImpl ctrlImpl, boolean isServBgp) { + public BGPPipelineFactory(BGPController bgpController, boolean isBgpServ) { super(); - bgpCtrlImpl = ctrlImpl; - /* hold time*/ - readTimeoutHandler = new ReadTimeoutHandler(TIMER, bgpCtrlImpl.getConfig().getHoldTime()); + this.isBgpServ = isBgpServ; + this.bgpController = bgpController; + /* hold time */ + this.readTimeoutHandler = new ReadTimeoutHandler(TIMER, bgpController.getConfig().getHoldTime()); } @Override public ChannelPipeline getPipeline() throws Exception { - BGPChannelHandler handler = new BGPChannelHandler(bgpCtrlImpl); + BGPChannelHandler handler = new BGPChannelHandler(bgpController); ChannelPipeline pipeline = Channels.pipeline(); pipeline.addLast("bgpmessagedecoder", new BGPMessageDecoder()); pipeline.addLast("bgpmessageencoder", new BGPMessageEncoder()); pipeline.addLast("holdTime", readTimeoutHandler); - pipeline.addLast("PassiveHandler", handler); + if (isBgpServ) { + pipeline.addLast("PassiveHandler", handler); + } else { + pipeline.addLast("ActiveHandler", handler); + } return pipeline; } diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPSessionInfo.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPSessionInfo.java deleted file mode 100755 index 207d7831..00000000 --- a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPSessionInfo.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright 2015 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.bgp.controller.impl; - -import org.onosproject.bgp.controller.BGPId; -import org.onosproject.bgpio.protocol.BGPVersion; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Class maintains BGP peer session info. - */ -public class BGPSessionInfo { - - protected final Logger log = LoggerFactory.getLogger(BGPSessionInfo.class); - private BGPId remoteBgpId; - private BGPVersion remoteBgpVersion; - private short remoteBgpASNum; - private short remoteBgpholdTime; - private int remoteBgpIdentifier; - private short negotiatedholdTime; - - /** - * Gets the negotiated hold time for the session. - * - * @return negotiated hold time. - */ - public short getNegotiatedholdTime() { - return negotiatedholdTime; - } - - /** - * Sets the negotiated hold time for the session. - * - * @param negotiatedholdTime negotiated hold time. - */ - public void setNegotiatedholdTime(short negotiatedholdTime) { - this.negotiatedholdTime = negotiatedholdTime; - } - - /** - * Gets the BGP ID of BGP peer. - * - * @return bgp ID. - */ - public BGPId getRemoteBgpId() { - return remoteBgpId; - } - - /** - * Sets the BGP ID of bgp peer. - * - * @param bgpId BGP ID to set. - */ - public void setRemoteBgpId(BGPId bgpId) { - log.debug("Remote BGP ID {}", bgpId); - this.remoteBgpId = bgpId; - } - - /** - * Gets the BGP version of peer. - * - * @return bgp version. - */ - public BGPVersion getRemoteBgpVersion() { - return remoteBgpVersion; - } - - /** - * Sets the BGP version for this bgp peer. - * - * @param bgpVersion bgp version to set. - */ - public void setRemoteBgpVersion(BGPVersion bgpVersion) { - log.debug("Remote BGP version {}", bgpVersion); - this.remoteBgpVersion = bgpVersion; - } - - /** - * Gets the BGP remote bgp AS number. - * - * @return remoteBgpASNum peer AS number. - */ - public short getRemoteBgpASNum() { - return remoteBgpASNum; - } - - /** - * Sets the AS Number for this bgp peer. - * - * @param bgpASNum the autonomous system number value to set. - */ - public void setRemoteBgpASNum(short bgpASNum) { - log.debug("Remote BGP AS number {}", bgpASNum); - this.remoteBgpASNum = bgpASNum; - } - - /** - * Gets the BGP peer hold time. - * - * @return bgp hold time. - */ - public short getRemoteBgpHoldTime() { - return remoteBgpholdTime; - } - - /** - * Sets the hold time for this bgp peer. - * - * @param holdTime the hold timer value to set. - */ - public void setRemoteBgpHoldTime(short holdTime) { - log.debug("Remote BGP HoldTime {}", holdTime); - this.remoteBgpholdTime = holdTime; - } - - /** - * Gets the BGP version for this bgp peer. - * - * @return bgp identifier. - */ - public int getRemoteBgpIdentifier() { - return remoteBgpIdentifier; - } - - /** - * Sets the peer identifier value. - * - * @param bgpIdentifier the bgp peer identifier value. - */ - public void setRemoteBgpIdentifier(int bgpIdentifier) { - log.debug("Remote BGP Identifier {}", bgpIdentifier); - this.remoteBgpIdentifier = bgpIdentifier; - } -} diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/Controller.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/Controller.java index 402e8c94..017c39e5 100755 --- a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/Controller.java +++ b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/Controller.java @@ -24,11 +24,17 @@ import java.util.HashMap; import java.util.Map; import java.util.concurrent.Executors; +import org.jboss.netty.bootstrap.ClientBootstrap; import org.jboss.netty.bootstrap.ServerBootstrap; import org.jboss.netty.channel.ChannelPipelineFactory; import org.jboss.netty.channel.group.ChannelGroup; import org.jboss.netty.channel.group.DefaultChannelGroup; +import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory; import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory; +import org.onosproject.bgp.controller.BGPController; +import org.onosproject.bgpio.protocol.BGPFactories; +import org.onosproject.bgpio.protocol.BGPFactory; +import org.onosproject.bgpio.protocol.BGPVersion; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -38,36 +44,45 @@ import org.slf4j.LoggerFactory; */ public class Controller { - protected static final Logger log = LoggerFactory.getLogger(Controller.class); + private static final Logger log = LoggerFactory.getLogger(Controller.class); + + private static final BGPFactory FACTORY4 = BGPFactories.getFactory(BGPVersion.BGP_4); private ChannelGroup cg; // Configuration options private static final short BGP_PORT_NUM = 179; - private int workerThreads = 16; + private final int workerThreads = 16; + private final int peerWorkerThreads = 16; // Start time of the controller - protected long systemStartTime; + private long systemStartTime; private NioServerSocketChannelFactory serverExecFactory; + private NioClientSocketChannelFactory peerExecFactory; + private static ClientBootstrap peerBootstrap; + private BGPController bgpController; // Perf. related configuration - protected static final int SEND_BUFFER_SIZE = 4 * 1024 * 1024; - - BGPControllerImpl bgpCtrlImpl; + private static final int SEND_BUFFER_SIZE = 4 * 1024 * 1024; /** - * Constructor to initialize parameter. + * Constructor to initialize the values. * - * @param bgpCtrlImpl BGP controller Impl instance + * @param bgpController bgp controller instance */ - public Controller(BGPControllerImpl bgpCtrlImpl) { - this.bgpCtrlImpl = bgpCtrlImpl; + public Controller(BGPController bgpController) { + this.bgpController = bgpController; } - // *************** - // Getters/Setters - // *************** + /** + * Returns factory version for processing BGP messages. + * + * @return instance of factory version + */ + static BGPFactory getBGPMessageFactory4() { + return FACTORY4; + } /** * To get system start time. @@ -78,16 +93,20 @@ public class Controller { return (this.systemStartTime); } - // ************** - // Initialization - // ************** - /** * Tell controller that we're ready to accept bgp peer connections. */ public void run() { try { + + peerBootstrap = createPeerBootStrap(); + + peerBootstrap.setOption("reuseAddr", true); + peerBootstrap.setOption("child.keepAlive", true); + peerBootstrap.setOption("child.tcpNoDelay", true); + peerBootstrap.setOption("child.sendBufferSize", Controller.SEND_BUFFER_SIZE); + final ServerBootstrap bootstrap = createServerBootStrap(); bootstrap.setOption("reuseAddr", true); @@ -95,7 +114,7 @@ public class Controller { bootstrap.setOption("child.tcpNoDelay", true); bootstrap.setOption("child.sendBufferSize", Controller.SEND_BUFFER_SIZE); - ChannelPipelineFactory pfact = new BGPPipelineFactory(bgpCtrlImpl, true); + ChannelPipelineFactory pfact = new BGPPipelineFactory(bgpController, true); bootstrap.setPipelineFactory(pfact); InetSocketAddress sa = new InetSocketAddress(getBgpPortNum()); @@ -129,6 +148,36 @@ public class Controller { } /** + * Creates peer boot strap. + * + * @return ClientBootstrap + */ + private ClientBootstrap createPeerBootStrap() { + + if (peerWorkerThreads == 0) { + peerExecFactory = new NioClientSocketChannelFactory( + Executors.newCachedThreadPool(groupedThreads("onos/bgp", "boss-%d")), + Executors.newCachedThreadPool(groupedThreads("onos/bgp", "worker-%d"))); + return new ClientBootstrap(peerExecFactory); + } else { + peerExecFactory = new NioClientSocketChannelFactory( + Executors.newCachedThreadPool(groupedThreads("onos/bgp", "boss-%d")), + Executors.newCachedThreadPool(groupedThreads("onos/bgp", "worker-%d")), + peerWorkerThreads); + return new ClientBootstrap(peerExecFactory); + } + } + + /** + * Gets peer bootstrap. + * + * @return peer bootstrap + */ + public static ClientBootstrap peerBootstrap() { + return peerBootstrap; + } + + /** * Initialize internal data structures. */ public void init() { @@ -137,10 +186,11 @@ public class Controller { this.systemStartTime = System.currentTimeMillis(); } - // ************** - // Utility methods - // ************** - + /** + * Gets run time memory. + * + * @return m run time memory + */ public Map<String, Long> getMemory() { Map<String, Long> m = new HashMap<>(); Runtime runtime = Runtime.getRuntime(); @@ -149,6 +199,11 @@ public class Controller { return m; } + /** + * Gets UP time. + * + * @return UP time + */ public Long getUptime() { RuntimeMXBean rb = ManagementFactory.getRuntimeMXBean(); return rb.getUptime(); @@ -169,6 +224,7 @@ public class Controller { public void stop() { log.info("Stopped"); serverExecFactory.shutdown(); + peerExecFactory.shutdown(); cg.close(); } |