diff options
Diffstat (limited to 'framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpOpen.java')
-rw-r--r-- | framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpOpen.java | 507 |
1 files changed, 0 insertions, 507 deletions
diff --git a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpOpen.java b/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpOpen.java deleted file mode 100644 index 1ccb6b6b..00000000 --- a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpOpen.java +++ /dev/null @@ -1,507 +0,0 @@ -/* - * Copyright 2014-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.routing.bgp; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.onlab.packet.Ip4Address; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * A class for handling BGP OPEN messages. - */ -final class BgpOpen { - private static final Logger log = LoggerFactory.getLogger(BgpOpen.class); - - /** - * Default constructor. - * <p> - * The constructor is private to prevent creating an instance of - * this utility class. - */ - private BgpOpen() { - } - - /** - * Processes BGP OPEN message. - * - * @param bgpSession the BGP Session to use - * @param ctx the Channel Handler Context - * @param message the message to process - */ - static void processBgpOpen(BgpSession bgpSession, - ChannelHandlerContext ctx, - ChannelBuffer message) { - int minLength = - BgpConstants.BGP_OPEN_MIN_LENGTH - BgpConstants.BGP_HEADER_LENGTH; - if (message.readableBytes() < minLength) { - log.debug("BGP RX OPEN Error from {}: " + - "Message length {} too short. Must be at least {}", - bgpSession.remoteInfo().address(), - message.readableBytes(), minLength); - // - // ERROR: Bad Message Length - // - // Send NOTIFICATION and close the connection - ChannelBuffer txMessage = - BgpNotification.prepareBgpNotificationBadMessageLength( - message.readableBytes() + BgpConstants.BGP_HEADER_LENGTH); - ctx.getChannel().write(txMessage); - bgpSession.closeSession(ctx); - return; - } - - // - // Parse the OPEN message - // - // Remote BGP version - int remoteBgpVersion = message.readUnsignedByte(); - if (remoteBgpVersion != BgpConstants.BGP_VERSION) { - log.debug("BGP RX OPEN Error from {}: " + - "Unsupported BGP version {}. Should be {}", - bgpSession.remoteInfo().address(), remoteBgpVersion, - BgpConstants.BGP_VERSION); - // - // ERROR: Unsupported Version Number - // - // Send NOTIFICATION and close the connection - int errorCode = BgpConstants.Notifications.OpenMessageError.ERROR_CODE; - int errorSubcode = BgpConstants.Notifications.OpenMessageError.UNSUPPORTED_VERSION_NUMBER; - ChannelBuffer data = ChannelBuffers.buffer(2); - data.writeShort(BgpConstants.BGP_VERSION); - ChannelBuffer txMessage = - BgpNotification.prepareBgpNotification(errorCode, errorSubcode, - data); - ctx.getChannel().write(txMessage); - bgpSession.closeSession(ctx); - return; - } - bgpSession.remoteInfo().setBgpVersion(remoteBgpVersion); - - // Remote AS number - long remoteAs = message.readUnsignedShort(); - bgpSession.remoteInfo().setAsNumber(remoteAs); - // - // NOTE: Currently, the local AS number is always set to the remote AS. - // This is done, because the peer setup is always iBGP. - // In the future, the local AS number should be configured as part - // of an explicit BGP peering configuration. - // - bgpSession.localInfo().setAsNumber(remoteAs); - - // Remote Hold Time - long remoteHoldtime = message.readUnsignedShort(); - if ((remoteHoldtime != 0) && - (remoteHoldtime < BgpConstants.BGP_KEEPALIVE_MIN_HOLDTIME)) { - log.debug("BGP RX OPEN Error from {}: " + - "Unacceptable Hold Time field {}. " + - "Should be 0 or at least {}", - bgpSession.remoteInfo().address(), remoteHoldtime, - BgpConstants.BGP_KEEPALIVE_MIN_HOLDTIME); - // - // ERROR: Unacceptable Hold Time - // - // Send NOTIFICATION and close the connection - int errorCode = BgpConstants.Notifications.OpenMessageError.ERROR_CODE; - int errorSubcode = BgpConstants.Notifications.OpenMessageError.UNACCEPTABLE_HOLD_TIME; - ChannelBuffer txMessage = - BgpNotification.prepareBgpNotification(errorCode, errorSubcode, - null); - ctx.getChannel().write(txMessage); - bgpSession.closeSession(ctx); - return; - } - bgpSession.remoteInfo().setHoldtime(remoteHoldtime); - // - // NOTE: Currently. the local BGP Holdtime is always set to the remote - // BGP holdtime. - // In the future, the local BGP Holdtime should be configured as part - // of an explicit BGP peering configuration. - // - bgpSession.localInfo().setHoldtime(remoteHoldtime); - - // Remote BGP Identifier - Ip4Address remoteBgpId = - Ip4Address.valueOf((int) message.readUnsignedInt()); - bgpSession.remoteInfo().setBgpId(remoteBgpId); - - // Parse the Optional Parameters - try { - parseOptionalParameters(bgpSession, ctx, message); - } catch (BgpMessage.BgpParseException e) { - // ERROR: Error parsing optional parameters - log.debug("BGP RX OPEN Error from {}: " + - "Exception parsing Optional Parameters: {}", - bgpSession.remoteInfo().address(), e); - // - // ERROR: Invalid Optional Parameters: Unspecific - // - // Send NOTIFICATION and close the connection - int errorCode = BgpConstants.Notifications.OpenMessageError.ERROR_CODE; - int errorSubcode = BgpConstants.Notifications.ERROR_SUBCODE_UNSPECIFIC; - ChannelBuffer txMessage = - BgpNotification.prepareBgpNotification(errorCode, errorSubcode, - null); - ctx.getChannel().write(txMessage); - bgpSession.closeSession(ctx); - return; - } - - // - // NOTE: Prepare the BGP OPEN message before the original local AS - // is overwritten by the 4-octet AS number - // - ChannelBuffer txOpenMessage = prepareBgpOpen(bgpSession.localInfo()); - - // - // Use the 4-octet AS number in lieu of the "My AS" field - // See RFC 6793, Section 4.1, second paragraph. - // - if (bgpSession.remoteInfo().as4OctetCapability()) { - long as4Number = bgpSession.remoteInfo().as4Number(); - bgpSession.remoteInfo().setAsNumber(as4Number); - bgpSession.localInfo().setAsNumber(as4Number); - } - - // - // Verify that the AS number is same for all other BGP Sessions - // NOTE: This check applies only for our use-case where all BGP - // sessions are iBGP. - // - for (BgpSession bs : bgpSession.getBgpSessionManager().getBgpSessions()) { - if ((bs.remoteInfo().asNumber() != 0) && - (bgpSession.remoteInfo().asNumber() != - bs.remoteInfo().asNumber())) { - log.debug("BGP RX OPEN Error from {}: Bad Peer AS {}. " + - "Expected {}", - bgpSession.remoteInfo().address(), - bgpSession.remoteInfo().asNumber(), - bs.remoteInfo().asNumber()); - // - // ERROR: Bad Peer AS - // - // Send NOTIFICATION and close the connection - int errorCode = BgpConstants.Notifications.OpenMessageError.ERROR_CODE; - int errorSubcode = BgpConstants.Notifications.OpenMessageError.BAD_PEER_AS; - ChannelBuffer txMessage = - BgpNotification.prepareBgpNotification(errorCode, - errorSubcode, null); - ctx.getChannel().write(txMessage); - bgpSession.closeSession(ctx); - return; - } - } - - log.debug("BGP RX OPEN message from {}: " + - "BGPv{} AS {} BGP-ID {} Holdtime {}", - bgpSession.remoteInfo().address(), - bgpSession.remoteInfo().bgpVersion(), - bgpSession.remoteInfo().asNumber(), - bgpSession.remoteInfo().bgpId(), - bgpSession.remoteInfo().holdtime()); - - // Send my OPEN followed by KEEPALIVE - ctx.getChannel().write(txOpenMessage); - // - ChannelBuffer txMessage = BgpKeepalive.prepareBgpKeepalive(); - ctx.getChannel().write(txMessage); - - // Start the KEEPALIVE timer - bgpSession.restartKeepaliveTimer(ctx); - - // Start the Session Timeout timer - bgpSession.restartSessionTimeoutTimer(ctx); - } - - /** - * Prepares BGP OPEN message. - * - * @param localInfo the BGP Session local information to use - * @return the message to transmit (BGP header included) - */ - static ChannelBuffer prepareBgpOpen(BgpSessionInfo localInfo) { - ChannelBuffer message = - ChannelBuffers.buffer(BgpConstants.BGP_MESSAGE_MAX_LENGTH); - - // - // Prepare the OPEN message payload - // - message.writeByte(localInfo.bgpVersion()); - message.writeShort((int) localInfo.asNumber()); - message.writeShort((int) localInfo.holdtime()); - message.writeInt(localInfo.bgpId().toInt()); - - // Prepare the optional BGP Capabilities - ChannelBuffer capabilitiesMessage = - prepareBgpOpenCapabilities(localInfo); - message.writeByte(capabilitiesMessage.readableBytes()); - message.writeBytes(capabilitiesMessage); - - return BgpMessage.prepareBgpMessage(BgpConstants.BGP_TYPE_OPEN, - message); - } - - /** - * Parses BGP OPEN Optional Parameters. - * - * @param bgpSession the BGP Session to use - * @param ctx the Channel Handler Context - * @param message the message to process - * @throws BgpMessage.BgpParseException - */ - private static void parseOptionalParameters(BgpSession bgpSession, - ChannelHandlerContext ctx, - ChannelBuffer message) - throws BgpMessage.BgpParseException { - - // - // Get and verify the Optional Parameters Length - // - int optParamLength = message.readUnsignedByte(); - if (optParamLength > message.readableBytes()) { - // ERROR: Invalid Optional Parameter Length - String errorMsg = "Invalid Optional Parameter Length field " + - optParamLength + ". Remaining Optional Parameters " + - message.readableBytes(); - throw new BgpMessage.BgpParseException(errorMsg); - } - if (optParamLength == 0) { - return; // No Optional Parameters - } - - // - // Parse the Optional Parameters - // - int optParamEnd = message.readerIndex() + optParamLength; - while (message.readerIndex() < optParamEnd) { - int paramType = message.readUnsignedByte(); - if (message.readerIndex() >= optParamEnd) { - // ERROR: Malformed Optional Parameters - String errorMsg = "Malformed Optional Parameters"; - throw new BgpMessage.BgpParseException(errorMsg); - } - int paramLen = message.readUnsignedByte(); - if (message.readerIndex() + paramLen > optParamEnd) { - // ERROR: Malformed Optional Parameters - String errorMsg = "Malformed Optional Parameters"; - throw new BgpMessage.BgpParseException(errorMsg); - } - - // - // Extract the Optional Parameter Value based on the Parameter Type - // - switch (paramType) { - case BgpConstants.Open.Capabilities.TYPE: - // Optional Parameter Type: Capabilities - if (paramLen < BgpConstants.Open.Capabilities.MIN_LENGTH) { - // ERROR: Malformed Param Type - String errorMsg = "Malformed Capabilities Optional " - + "Parameter Type " + paramType; - throw new BgpMessage.BgpParseException(errorMsg); - } - int paramEnd = message.readerIndex() + paramLen; - // Parse Capabilities - while (message.readerIndex() < paramEnd) { - if (paramEnd - message.readerIndex() < - BgpConstants.Open.Capabilities.MIN_LENGTH) { - String errorMsg = "Malformed Capabilities"; - throw new BgpMessage.BgpParseException(errorMsg); - } - int capabCode = message.readUnsignedByte(); - int capabLen = message.readUnsignedByte(); - if (message.readerIndex() + capabLen > paramEnd) { - // ERROR: Malformed Capability - String errorMsg = "Malformed Capability instance with " - + "code " + capabCode; - throw new BgpMessage.BgpParseException(errorMsg); - } - - switch (capabCode) { - case BgpConstants.Open.Capabilities.MultiprotocolExtensions.CODE: - // Multiprotocol Extensions Capabilities (RFC 4760) - if (capabLen != BgpConstants.Open.Capabilities.MultiprotocolExtensions.LENGTH) { - // ERROR: Multiprotocol Extension Length Error - String errorMsg = "Multiprotocol Extension Length Error"; - throw new BgpMessage.BgpParseException(errorMsg); - } - // Decode the AFI (2 octets) and SAFI (1 octet) - int afi = message.readUnsignedShort(); - int reserved = message.readUnsignedByte(); - int safi = message.readUnsignedByte(); - log.debug("BGP RX OPEN Capability: AFI = {} SAFI = {}", - afi, safi); - // - // Setup the AFI/SAFI in the BgpSession - // - // NOTE: For now we just copy the remote AFI/SAFI setting - // to the local configuration. - // - if (afi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV4 && - safi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_UNICAST) { - bgpSession.remoteInfo().setIpv4Unicast(); - bgpSession.localInfo().setIpv4Unicast(); - } else if (afi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV4 && - safi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_MULTICAST) { - bgpSession.remoteInfo().setIpv4Multicast(); - bgpSession.localInfo().setIpv4Multicast(); - } else if (afi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV6 && - safi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_UNICAST) { - bgpSession.remoteInfo().setIpv6Unicast(); - bgpSession.localInfo().setIpv6Unicast(); - } else if (afi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV6 && - safi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_MULTICAST) { - bgpSession.remoteInfo().setIpv6Multicast(); - bgpSession.localInfo().setIpv6Multicast(); - } else { - log.debug("BGP RX OPEN Capability: Unknown AFI = {} SAFI = {}", - afi, safi); - } - break; - - case BgpConstants.Open.Capabilities.As4Octet.CODE: - // Support for 4-octet AS Number Capabilities (RFC 6793) - if (capabLen != BgpConstants.Open.Capabilities.As4Octet.LENGTH) { - // ERROR: 4-octet AS Number Capability Length Error - String errorMsg = "4-octet AS Number Capability Length Error"; - throw new BgpMessage.BgpParseException(errorMsg); - } - long as4Number = message.readUnsignedInt(); - - bgpSession.remoteInfo().setAs4OctetCapability(); - bgpSession.remoteInfo().setAs4Number(as4Number); - - // - // Copy remote 4-octet AS Number Capabilities and AS - // Number. This is a temporary setting until local AS - // number configuration is supported. - // - bgpSession.localInfo().setAs4OctetCapability(); - bgpSession.localInfo().setAs4Number(as4Number); - log.debug("BGP RX OPEN Capability: AS4 Number = {}", - as4Number); - break; - - default: - // Unknown Capability: ignore it - log.debug("BGP RX OPEN Capability Code = {} Length = {}", - capabCode, capabLen); - message.readBytes(capabLen); - break; - } - - - } - break; - default: - // Unknown Parameter Type: ignore it - log.debug("BGP RX OPEN Parameter Type = {} Length = {}", - paramType, paramLen); - message.readBytes(paramLen); - break; - } - } - } - - /** - * Prepares the Capabilities for the BGP OPEN message. - * - * @param localInfo the BGP Session local information to use - * @return the buffer with the BGP Capabilities to transmit - */ - private static ChannelBuffer prepareBgpOpenCapabilities( - BgpSessionInfo localInfo) { - ChannelBuffer message = - ChannelBuffers.buffer(BgpConstants.BGP_MESSAGE_MAX_LENGTH); - - // - // Write the Multiprotocol Extensions Capabilities - // - - // IPv4 unicast - if (localInfo.ipv4Unicast()) { - message.writeByte(BgpConstants.Open.Capabilities.TYPE); // Param type - message.writeByte(BgpConstants.Open.Capabilities.MIN_LENGTH + - BgpConstants.Open.Capabilities.MultiprotocolExtensions.LENGTH); // Param len - message.writeByte( - BgpConstants.Open.Capabilities.MultiprotocolExtensions.CODE); // Capab. code - message.writeByte( - BgpConstants.Open.Capabilities.MultiprotocolExtensions.LENGTH); // Capab. len - message.writeShort( - BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV4); - message.writeByte(0); // Reserved field - message.writeByte( - BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_UNICAST); - } - // IPv4 multicast - if (localInfo.ipv4Multicast()) { - message.writeByte(BgpConstants.Open.Capabilities.TYPE); // Param type - message.writeByte(BgpConstants.Open.Capabilities.MIN_LENGTH + - BgpConstants.Open.Capabilities.MultiprotocolExtensions.LENGTH); // Param len - message.writeByte( - BgpConstants.Open.Capabilities.MultiprotocolExtensions.CODE); // Capab. code - message.writeByte( - BgpConstants.Open.Capabilities.MultiprotocolExtensions.LENGTH); // Capab. len - message.writeShort( - BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV4); - message.writeByte(0); // Reserved field - message.writeByte( - BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_MULTICAST); - } - // IPv6 unicast - if (localInfo.ipv6Unicast()) { - message.writeByte(BgpConstants.Open.Capabilities.TYPE); // Param type - message.writeByte(BgpConstants.Open.Capabilities.MIN_LENGTH + - BgpConstants.Open.Capabilities.MultiprotocolExtensions.LENGTH); // Param len - message.writeByte( - BgpConstants.Open.Capabilities.MultiprotocolExtensions.CODE); // Capab. code - message.writeByte( - BgpConstants.Open.Capabilities.MultiprotocolExtensions.LENGTH); // Capab. len - message.writeShort( - BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV6); - message.writeByte(0); // Reserved field - message.writeByte( - BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_UNICAST); - } - // IPv6 multicast - if (localInfo.ipv6Multicast()) { - message.writeByte(BgpConstants.Open.Capabilities.TYPE); // Param type - message.writeByte(BgpConstants.Open.Capabilities.MIN_LENGTH + - BgpConstants.Open.Capabilities.MultiprotocolExtensions.LENGTH); // Param len - message.writeByte( - BgpConstants.Open.Capabilities.MultiprotocolExtensions.CODE); // Capab. code - message.writeByte( - BgpConstants.Open.Capabilities.MultiprotocolExtensions.LENGTH); // Capab. len - message.writeShort( - BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV6); - message.writeByte(0); // Reserved field - message.writeByte( - BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_MULTICAST); - } - - // 4 octet AS path capability - if (localInfo.as4OctetCapability()) { - message.writeByte(BgpConstants.Open.Capabilities.TYPE); // Param type - message.writeByte(BgpConstants.Open.Capabilities.MIN_LENGTH + - BgpConstants.Open.Capabilities.As4Octet.LENGTH); // Param len - message.writeByte(BgpConstants.Open.Capabilities.As4Octet.CODE); // Capab. code - message.writeByte(BgpConstants.Open.Capabilities.As4Octet.LENGTH); // Capab. len - message.writeInt((int) localInfo.as4Number()); - } - return message; - } -} |