blob: ef9f1d38085c1c803050cdc88cbe1610906dd8c5 [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Jonathan Hartf4bd0482017-01-27 15:11:18 -08002 * Copyright 2017-present Open Networking Laboratory
Thomas Vachuska781d18b2014-10-27 10:31:25 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
Thomas Vachuska781d18b2014-10-27 10:31:25 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
Thomas Vachuska781d18b2014-10-27 10:31:25 -070015 */
Jonathan Hartf4bd0482017-01-27 15:11:18 -080016
Jonathan Hart41349e92015-02-09 14:14:02 -080017package org.onosproject.routing.bgp;
Jonathan Hart20d8e512014-10-16 11:05:52 -070018
19import org.jboss.netty.buffer.ChannelBuffer;
20import org.jboss.netty.channel.Channel;
21import org.jboss.netty.channel.ChannelHandlerContext;
22import org.jboss.netty.handler.codec.frame.FrameDecoder;
Pavlin Radoslavov6b570732014-11-06 13:16:45 -080023import org.onlab.packet.Ip4Address;
Jonathan Hart20d8e512014-10-16 11:05:52 -070024
Jonathan Hart41349e92015-02-09 14:14:02 -080025import java.util.concurrent.CountDownLatch;
26
Jonathan Hart20d8e512014-10-16 11:05:52 -070027/**
28 * Class for handling the decoding of the BGP messages at the remote
29 * BGP peer session.
30 */
31class TestBgpPeerFrameDecoder extends FrameDecoder {
Pavlin Radoslavov4b5acae2015-01-28 17:09:45 -080032 final BgpSessionInfo remoteInfo = new BgpSessionInfo();
Jonathan Hart20d8e512014-10-16 11:05:52 -070033
34 final CountDownLatch receivedOpenMessageLatch = new CountDownLatch(1);
35 final CountDownLatch receivedKeepaliveMessageLatch = new CountDownLatch(1);
36
37 @Override
38 protected Object decode(ChannelHandlerContext ctx,
39 Channel channel,
40 ChannelBuffer buf) throws Exception {
41 // Test for minimum length of the BGP message
42 if (buf.readableBytes() < BgpConstants.BGP_HEADER_LENGTH) {
43 // No enough data received
44 return null;
45 }
46
47 //
48 // Mark the current buffer position in case we haven't received
49 // the whole message.
50 //
51 buf.markReaderIndex();
52
53 //
54 // Read and check the BGP message Marker field: it must be all ones
55 //
56 byte[] marker = new byte[BgpConstants.BGP_HEADER_MARKER_LENGTH];
57 buf.readBytes(marker);
58 for (int i = 0; i < marker.length; i++) {
59 if (marker[i] != (byte) 0xff) {
60 // ERROR: Connection Not Synchronized. Close the channel.
61 ctx.getChannel().close();
62 return null;
63 }
64 }
65
66 //
67 // Read and check the BGP message Length field
68 //
69 int length = buf.readUnsignedShort();
70 if ((length < BgpConstants.BGP_HEADER_LENGTH) ||
71 (length > BgpConstants.BGP_MESSAGE_MAX_LENGTH)) {
72 // ERROR: Bad Message Length. Close the channel.
73 ctx.getChannel().close();
74 return null;
75 }
76
77 //
78 // Test whether the rest of the message is received:
79 // So far we have read the Marker (16 octets) and the
80 // Length (2 octets) fields.
81 //
82 int remainingMessageLen =
83 length - BgpConstants.BGP_HEADER_MARKER_LENGTH - 2;
84 if (buf.readableBytes() < remainingMessageLen) {
85 // No enough data received
86 buf.resetReaderIndex();
87 return null;
88 }
89
90 //
91 // Read the BGP message Type field, and process based on that type
92 //
93 int type = buf.readUnsignedByte();
94 remainingMessageLen--; // Adjust after reading the type
95 ChannelBuffer message = buf.readBytes(remainingMessageLen);
96
97 //
98 // Process the remaining of the message based on the message type
99 //
100 switch (type) {
101 case BgpConstants.BGP_TYPE_OPEN:
102 processBgpOpen(ctx, message);
103 break;
104 case BgpConstants.BGP_TYPE_UPDATE:
105 // NOTE: Not used as part of the test, because ONOS does not
106 // originate UPDATE messages.
107 break;
108 case BgpConstants.BGP_TYPE_NOTIFICATION:
109 // NOTE: Not used as part of the testing (yet)
110 break;
111 case BgpConstants.BGP_TYPE_KEEPALIVE:
112 processBgpKeepalive(ctx, message);
113 break;
114 default:
115 // ERROR: Bad Message Type. Close the channel.
116 ctx.getChannel().close();
117 return null;
118 }
119
120 return null;
121 }
122
123 /**
124 * Processes BGP OPEN message.
125 *
126 * @param ctx the Channel Handler Context.
127 * @param message the message to process.
128 */
129 private void processBgpOpen(ChannelHandlerContext ctx,
130 ChannelBuffer message) {
131 int minLength =
132 BgpConstants.BGP_OPEN_MIN_LENGTH - BgpConstants.BGP_HEADER_LENGTH;
133 if (message.readableBytes() < minLength) {
134 // ERROR: Bad Message Length. Close the channel.
135 ctx.getChannel().close();
136 return;
137 }
138
139 //
140 // Parse the OPEN message
141 //
Pavlin Radoslavov4b5acae2015-01-28 17:09:45 -0800142 remoteInfo.setBgpVersion(message.readUnsignedByte());
143 remoteInfo.setAsNumber(message.readUnsignedShort());
144 remoteInfo.setHoldtime(message.readUnsignedShort());
145 remoteInfo.setBgpId(Ip4Address.valueOf((int) message.readUnsignedInt()));
Jonathan Hart20d8e512014-10-16 11:05:52 -0700146 // Optional Parameters
147 int optParamLen = message.readUnsignedByte();
148 if (message.readableBytes() < optParamLen) {
149 // ERROR: Bad Message Length. Close the channel.
150 ctx.getChannel().close();
151 return;
152 }
153 message.readBytes(optParamLen); // NOTE: data ignored
154
155 // BGP OPEN message successfully received
156 receivedOpenMessageLatch.countDown();
157 }
158
159 /**
160 * Processes BGP KEEPALIVE message.
161 *
162 * @param ctx the Channel Handler Context.
163 * @param message the message to process.
164 */
165 private void processBgpKeepalive(ChannelHandlerContext ctx,
166 ChannelBuffer message) {
167 if (message.readableBytes() + BgpConstants.BGP_HEADER_LENGTH !=
168 BgpConstants.BGP_KEEPALIVE_EXPECTED_LENGTH) {
169 // ERROR: Bad Message Length. Close the channel.
170 ctx.getChannel().close();
171 return;
172 }
173 // BGP KEEPALIVE message successfully received
174 receivedKeepaliveMessageLatch.countDown();
175 }
176}