diff options
Diffstat (limited to 'framework/src/onos/apps/routing/src/test/java/org/onosproject/routing/bgp/TestBgpPeerFrameDecoder.java')
-rw-r--r-- | framework/src/onos/apps/routing/src/test/java/org/onosproject/routing/bgp/TestBgpPeerFrameDecoder.java | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/framework/src/onos/apps/routing/src/test/java/org/onosproject/routing/bgp/TestBgpPeerFrameDecoder.java b/framework/src/onos/apps/routing/src/test/java/org/onosproject/routing/bgp/TestBgpPeerFrameDecoder.java new file mode 100644 index 00000000..b4ff40d2 --- /dev/null +++ b/framework/src/onos/apps/routing/src/test/java/org/onosproject/routing/bgp/TestBgpPeerFrameDecoder.java @@ -0,0 +1,175 @@ +/* + * 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.channel.Channel; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.handler.codec.frame.FrameDecoder; +import org.onlab.packet.Ip4Address; + +import java.util.concurrent.CountDownLatch; + +/** + * Class for handling the decoding of the BGP messages at the remote + * BGP peer session. + */ +class TestBgpPeerFrameDecoder extends FrameDecoder { + final BgpSessionInfo remoteInfo = new BgpSessionInfo(); + + final CountDownLatch receivedOpenMessageLatch = new CountDownLatch(1); + final CountDownLatch receivedKeepaliveMessageLatch = new CountDownLatch(1); + + @Override + protected Object decode(ChannelHandlerContext ctx, + Channel channel, + ChannelBuffer buf) throws Exception { + // Test for minimum length of the BGP message + if (buf.readableBytes() < BgpConstants.BGP_HEADER_LENGTH) { + // No enough data received + return null; + } + + // + // Mark the current buffer position in case we haven't received + // the whole message. + // + buf.markReaderIndex(); + + // + // Read and check the BGP message Marker field: it must be all ones + // + byte[] marker = new byte[BgpConstants.BGP_HEADER_MARKER_LENGTH]; + buf.readBytes(marker); + for (int i = 0; i < marker.length; i++) { + if (marker[i] != (byte) 0xff) { + // ERROR: Connection Not Synchronized. Close the channel. + ctx.getChannel().close(); + return null; + } + } + + // + // Read and check the BGP message Length field + // + int length = buf.readUnsignedShort(); + if ((length < BgpConstants.BGP_HEADER_LENGTH) || + (length > BgpConstants.BGP_MESSAGE_MAX_LENGTH)) { + // ERROR: Bad Message Length. Close the channel. + ctx.getChannel().close(); + return null; + } + + // + // Test whether the rest of the message is received: + // So far we have read the Marker (16 octets) and the + // Length (2 octets) fields. + // + int remainingMessageLen = + length - BgpConstants.BGP_HEADER_MARKER_LENGTH - 2; + if (buf.readableBytes() < remainingMessageLen) { + // No enough data received + buf.resetReaderIndex(); + return null; + } + + // + // Read the BGP message Type field, and process based on that type + // + int type = buf.readUnsignedByte(); + remainingMessageLen--; // Adjust after reading the type + ChannelBuffer message = buf.readBytes(remainingMessageLen); + + // + // Process the remaining of the message based on the message type + // + switch (type) { + case BgpConstants.BGP_TYPE_OPEN: + processBgpOpen(ctx, message); + break; + case BgpConstants.BGP_TYPE_UPDATE: + // NOTE: Not used as part of the test, because ONOS does not + // originate UPDATE messages. + break; + case BgpConstants.BGP_TYPE_NOTIFICATION: + // NOTE: Not used as part of the testing (yet) + break; + case BgpConstants.BGP_TYPE_KEEPALIVE: + processBgpKeepalive(ctx, message); + break; + default: + // ERROR: Bad Message Type. Close the channel. + ctx.getChannel().close(); + return null; + } + + return null; + } + + /** + * Processes BGP OPEN message. + * + * @param ctx the Channel Handler Context. + * @param message the message to process. + */ + private void processBgpOpen(ChannelHandlerContext ctx, + ChannelBuffer message) { + int minLength = + BgpConstants.BGP_OPEN_MIN_LENGTH - BgpConstants.BGP_HEADER_LENGTH; + if (message.readableBytes() < minLength) { + // ERROR: Bad Message Length. Close the channel. + ctx.getChannel().close(); + return; + } + + // + // Parse the OPEN message + // + remoteInfo.setBgpVersion(message.readUnsignedByte()); + remoteInfo.setAsNumber(message.readUnsignedShort()); + remoteInfo.setHoldtime(message.readUnsignedShort()); + remoteInfo.setBgpId(Ip4Address.valueOf((int) message.readUnsignedInt())); + // Optional Parameters + int optParamLen = message.readUnsignedByte(); + if (message.readableBytes() < optParamLen) { + // ERROR: Bad Message Length. Close the channel. + ctx.getChannel().close(); + return; + } + message.readBytes(optParamLen); // NOTE: data ignored + + // BGP OPEN message successfully received + receivedOpenMessageLatch.countDown(); + } + + /** + * Processes BGP KEEPALIVE message. + * + * @param ctx the Channel Handler Context. + * @param message the message to process. + */ + private void processBgpKeepalive(ChannelHandlerContext ctx, + ChannelBuffer message) { + if (message.readableBytes() + BgpConstants.BGP_HEADER_LENGTH != + BgpConstants.BGP_KEEPALIVE_EXPECTED_LENGTH) { + // ERROR: Bad Message Length. Close the channel. + ctx.getChannel().close(); + return; + } + // BGP KEEPALIVE message successfully received + receivedKeepaliveMessageLatch.countDown(); + } +} |