Vidyashree Rama
Committed by Gerrit Code Review

BGP Controller test

Change-Id: I4bdafeec877d5fbfa79306717cf3033936e0fe59
...@@ -31,7 +31,7 @@ import com.google.common.base.MoreObjects; ...@@ -31,7 +31,7 @@ import com.google.common.base.MoreObjects;
31 /** 31 /**
32 * Provides BGP keep alive message. 32 * Provides BGP keep alive message.
33 */ 33 */
34 -class BGPKeepaliveMsgVer4 implements BGPKeepaliveMsg { 34 +public class BGPKeepaliveMsgVer4 implements BGPKeepaliveMsg {
35 35
36 /* 36 /*
37 <Keepalive Message>::= <Common Header> 37 <Keepalive Message>::= <Common Header>
...@@ -88,7 +88,7 @@ class BGPKeepaliveMsgVer4 implements BGPKeepaliveMsg { ...@@ -88,7 +88,7 @@ class BGPKeepaliveMsgVer4 implements BGPKeepaliveMsg {
88 /** 88 /**
89 * Default constructor. 89 * Default constructor.
90 */ 90 */
91 - BGPKeepaliveMsgVer4() { 91 + public BGPKeepaliveMsgVer4() {
92 } 92 }
93 93
94 /** 94 /**
......
...@@ -204,6 +204,15 @@ public class BGPControllerImpl implements BGPController { ...@@ -204,6 +204,15 @@ public class BGPControllerImpl implements BGPController {
204 204
205 } 205 }
206 206
207 + /**
208 + * Returns controller.
209 + *
210 + * @return controller
211 + */
212 + public Controller controller() {
213 + return this.ctrl;
214 + }
215 +
207 @Override 216 @Override
208 public ConcurrentHashMap<BGPId, BGPPeer> connectedPeers() { 217 public ConcurrentHashMap<BGPId, BGPPeer> connectedPeers() {
209 return connectedPeers; 218 return connectedPeers;
......
...@@ -26,6 +26,7 @@ import java.util.concurrent.Executors; ...@@ -26,6 +26,7 @@ import java.util.concurrent.Executors;
26 26
27 import org.jboss.netty.bootstrap.ClientBootstrap; 27 import org.jboss.netty.bootstrap.ClientBootstrap;
28 import org.jboss.netty.bootstrap.ServerBootstrap; 28 import org.jboss.netty.bootstrap.ServerBootstrap;
29 +import org.jboss.netty.channel.Channel;
29 import org.jboss.netty.channel.ChannelPipelineFactory; 30 import org.jboss.netty.channel.ChannelPipelineFactory;
30 import org.jboss.netty.channel.group.ChannelGroup; 31 import org.jboss.netty.channel.group.ChannelGroup;
31 import org.jboss.netty.channel.group.DefaultChannelGroup; 32 import org.jboss.netty.channel.group.DefaultChannelGroup;
...@@ -49,9 +50,12 @@ public class Controller { ...@@ -49,9 +50,12 @@ public class Controller {
49 private static final BGPFactory FACTORY4 = BGPFactories.getFactory(BGPVersion.BGP_4); 50 private static final BGPFactory FACTORY4 = BGPFactories.getFactory(BGPVersion.BGP_4);
50 51
51 private ChannelGroup cg; 52 private ChannelGroup cg;
53 + public Channel serverChannel;
52 54
53 // Configuration options 55 // Configuration options
54 private static final short BGP_PORT_NUM = 179; 56 private static final short BGP_PORT_NUM = 179;
57 + private static final short PORT_NUM_ZERO = 0;
58 + private static boolean isPortNumSet = false;
55 private final int workerThreads = 16; 59 private final int workerThreads = 16;
56 private final int peerWorkerThreads = 16; 60 private final int peerWorkerThreads = 16;
57 61
...@@ -119,7 +123,8 @@ public class Controller { ...@@ -119,7 +123,8 @@ public class Controller {
119 bootstrap.setPipelineFactory(pfact); 123 bootstrap.setPipelineFactory(pfact);
120 InetSocketAddress sa = new InetSocketAddress(getBgpPortNum()); 124 InetSocketAddress sa = new InetSocketAddress(getBgpPortNum());
121 cg = new DefaultChannelGroup(); 125 cg = new DefaultChannelGroup();
122 - cg.add(bootstrap.bind(sa)); 126 + serverChannel = bootstrap.bind(sa);
127 + cg.add(serverChannel);
123 log.info("Listening for Peer connection on {}", sa); 128 log.info("Listening for Peer connection on {}", sa);
124 } catch (Exception e) { 129 } catch (Exception e) {
125 throw new RuntimeException(e); 130 throw new RuntimeException(e);
...@@ -234,6 +239,16 @@ public class Controller { ...@@ -234,6 +239,16 @@ public class Controller {
234 * @return port number 239 * @return port number
235 */ 240 */
236 public static short getBgpPortNum() { 241 public static short getBgpPortNum() {
242 + if (isPortNumSet) {
243 + return PORT_NUM_ZERO;
244 + }
237 return BGP_PORT_NUM; 245 return BGP_PORT_NUM;
238 } 246 }
247 +
248 + /**
249 + * sets the isPortNumSet as true.
250 + */
251 + public void setBgpPortNum() {
252 + isPortNumSet = true;
253 + }
239 } 254 }
...\ No newline at end of file ...\ No newline at end of file
......
1 +/*
2 + * Copyright 2014-2015 Open Networking Laboratory
3 + *
4 + * 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
7 + *
8 + * 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.
15 + */
16 +package org.onosproject.bgp;
17 +
18 +import com.google.common.net.InetAddresses;
19 +import org.jboss.netty.bootstrap.ClientBootstrap;
20 +import org.jboss.netty.channel.Channel;
21 +import org.jboss.netty.channel.ChannelFactory;
22 +import org.jboss.netty.channel.ChannelPipeline;
23 +import org.jboss.netty.channel.ChannelPipelineFactory;
24 +import org.jboss.netty.channel.Channels;
25 +import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
26 +import org.junit.After;
27 +import org.junit.Before;
28 +import org.junit.Test;
29 +
30 +import static org.hamcrest.core.Is.is;
31 +import static org.junit.Assert.assertThat;
32 +
33 +import org.onlab.junit.TestUtils;
34 +
35 +import java.net.InetAddress;
36 +import java.net.InetSocketAddress;
37 +import java.net.SocketAddress;
38 +import java.util.LinkedList;
39 +import java.util.concurrent.Executors;
40 +import java.util.concurrent.TimeUnit;
41 +
42 +import org.slf4j.Logger;
43 +import org.slf4j.LoggerFactory;
44 +
45 +import org.onosproject.bgp.controller.BGPCfg;
46 +import org.onosproject.bgp.controller.impl.BGPControllerImpl;
47 +import org.onosproject.bgpio.types.BGPValueType;
48 +import org.onosproject.bgpio.types.FourOctetAsNumCapabilityTlv;
49 +import org.onosproject.bgpio.types.MultiProtocolExtnCapabilityTlv;
50 +
51 +/**
52 + * Test case for BGPControllerImpl.
53 + */
54 +public class BGPControllerImplTest {
55 +
56 + protected static final Logger log = LoggerFactory
57 + .getLogger(BGPControllerImplTest.class);
58 +
59 + private static final String IP_LOOPBACK_ID1 = "127.0.0.1";
60 +
61 + private static final int MESSAGE_TIMEOUT_MS = 3000;
62 + public byte version;
63 + public short asNumber;
64 + public short holdTime;
65 + public int bgpId = InetAddresses.coerceToInteger(InetAddresses.forString(IP_LOOPBACK_ID1));
66 + public boolean isLargeAsCapabilitySet = false;
67 + public LinkedList<BGPValueType> capabilityTlv = new LinkedList<>();
68 +
69 + @Before
70 + public void setUp() throws Exception {
71 + peer1 = new BgpPeerTest(version, asNumber,
72 + holdTime, bgpId, isLargeAsCapabilitySet,
73 + capabilityTlv);
74 +
75 + bgpControllerImpl = new BGPControllerImpl();
76 +
77 + // NOTE: We use port 0 to bind on any available port
78 + bgpControllerImpl.controller().setBgpPortNum();
79 + bgpControllerImpl.activate();
80 +
81 + Channel serverChannel = TestUtils.getField(bgpControllerImpl.controller(),
82 + "serverChannel");
83 + SocketAddress socketAddress = serverChannel.getLocalAddress();
84 + InetSocketAddress inetSocketAddress =
85 + (InetSocketAddress) socketAddress;
86 + InetAddress connectToAddress = InetAddresses.forString("127.0.0.1");
87 + connectToSocket = new InetSocketAddress(connectToAddress,
88 + inetSocketAddress.getPort());
89 +
90 + bgpControllerImpl.getConfig().setRouterId("1.1.1.1");
91 + bgpControllerImpl.getConfig().setAsNumber(200);
92 + bgpControllerImpl.getConfig().setHoldTime((short) 120);
93 + bgpControllerImpl.getConfig().setState(BGPCfg.State.IP_AS_CONFIGURED);
94 +
95 + bgpControllerImpl.getConfig().addPeer("127.0.0.1", 200);
96 + }
97 +
98 + @After
99 + public void tearDown() throws Exception {
100 + bgpControllerImpl.deactivate();
101 + bgpControllerImpl = null;
102 + }
103 +
104 + private BGPControllerImpl bgpControllerImpl;
105 +
106 + BgpPeerTest peer1;
107 +
108 + // The socket that the remote peers should connect to
109 + private InetSocketAddress connectToSocket;
110 +
111 + @Test
112 + public void bgpOpenMessageTest1() throws InterruptedException {
113 + peer1.peerChannelHandler.asNumber = 200;
114 + peer1.peerChannelHandler.version = 4;
115 + peer1.peerChannelHandler.holdTime = 120;
116 + peer1.connect(connectToSocket);
117 + boolean result;
118 + result = peer1.peerFrameDecoder.receivedOpenMessageLatch.await(
119 + MESSAGE_TIMEOUT_MS,
120 + TimeUnit.MILLISECONDS);
121 + assertThat(result, is(true));
122 + result = peer1.peerFrameDecoder.receivedKeepaliveMessageLatch.await(
123 + MESSAGE_TIMEOUT_MS,
124 + TimeUnit.MILLISECONDS);
125 + assertThat(result, is(true));
126 + }
127 +
128 + @Test
129 + public void bgpOpenMessageTest2() throws InterruptedException {
130 + // Open message with as number which is not configured at peer
131 + peer1.peerChannelHandler.asNumber = 500;
132 + peer1.peerChannelHandler.version = 4;
133 + peer1.peerChannelHandler.holdTime = 120;
134 + peer1.connect(connectToSocket);
135 +
136 + boolean result;
137 + result = peer1.peerFrameDecoder.receivedNotificationMessageLatch.await(
138 + MESSAGE_TIMEOUT_MS,
139 + TimeUnit.MILLISECONDS);
140 + assertThat(result, is(true));
141 + }
142 +
143 + @Test
144 + public void bgpOpenMessageTest3() throws InterruptedException {
145 + // Open message with invalid hold time value
146 + peer1.peerChannelHandler.asNumber = 200;
147 + peer1.peerChannelHandler.version = 4;
148 + peer1.peerChannelHandler.holdTime = 1;
149 + peer1.connect(connectToSocket);
150 +
151 + boolean result;
152 + result = peer1.peerFrameDecoder.receivedNotificationMessageLatch.await(
153 + MESSAGE_TIMEOUT_MS,
154 + TimeUnit.MILLISECONDS);
155 + assertThat(result, is(true));
156 + }
157 +
158 + @Test
159 + public void bgpOpenMessageTest4() throws InterruptedException {
160 + // Open message with invalid as number
161 + peer1.peerChannelHandler.asNumber = 200;
162 + peer1.peerChannelHandler.version = 4;
163 + peer1.peerChannelHandler.holdTime = 120;
164 + peer1.peerChannelHandler.isLargeAsCapabilitySet = true;
165 + BGPValueType tempTlv = new FourOctetAsNumCapabilityTlv(766545);
166 + peer1.peerChannelHandler.capabilityTlv.add(tempTlv);
167 + peer1.connect(connectToSocket);
168 +
169 + boolean result;
170 + result = peer1.peerFrameDecoder.receivedNotificationMessageLatch.await(
171 + MESSAGE_TIMEOUT_MS,
172 + TimeUnit.MILLISECONDS);
173 + assertThat(result, is(true));
174 + }
175 +
176 + @Test
177 + public void bgpOpenMessageTest5() throws InterruptedException {
178 + // Open message with LS capability
179 + short afi = 16388;
180 + byte res = 0;
181 + byte safi = 71;
182 + peer1.peerChannelHandler.asNumber = 200;
183 + peer1.peerChannelHandler.version = 4;
184 + peer1.peerChannelHandler.holdTime = 120;
185 + bgpControllerImpl.getConfig().setLsCapability(true);
186 + BGPValueType tempTlv1 = new MultiProtocolExtnCapabilityTlv(afi, res, safi);
187 + peer1.peerChannelHandler.capabilityTlv.add(tempTlv1);
188 + peer1.connect(connectToSocket);
189 +
190 + boolean result;
191 + result = peer1.peerFrameDecoder.receivedOpenMessageLatch.await(
192 + MESSAGE_TIMEOUT_MS,
193 + TimeUnit.MILLISECONDS);
194 + assertThat(result, is(true));
195 + result = peer1.peerFrameDecoder.receivedKeepaliveMessageLatch.await(
196 + MESSAGE_TIMEOUT_MS,
197 + TimeUnit.MILLISECONDS);
198 + assertThat(result, is(true));
199 + }
200 +
201 + @Test
202 + public void bgpOpenMessageTest6() throws InterruptedException {
203 + // Open message with as4 capability
204 + peer1.peerChannelHandler.asNumber = 200;
205 + peer1.peerChannelHandler.version = 4;
206 + peer1.peerChannelHandler.holdTime = 120;
207 + peer1.peerChannelHandler.isLargeAsCapabilitySet = true;
208 + bgpControllerImpl.getConfig().setLargeASCapability(true);
209 + BGPValueType tempTlv = new FourOctetAsNumCapabilityTlv(200);
210 + peer1.peerChannelHandler.capabilityTlv.add(tempTlv);
211 + peer1.connect(connectToSocket);
212 +
213 + boolean result;
214 + result = peer1.peerFrameDecoder.receivedOpenMessageLatch.await(
215 + MESSAGE_TIMEOUT_MS,
216 + TimeUnit.MILLISECONDS);
217 + assertThat(result, is(true));
218 + result = peer1.peerFrameDecoder.receivedKeepaliveMessageLatch.await(
219 + MESSAGE_TIMEOUT_MS,
220 + TimeUnit.MILLISECONDS);
221 + assertThat(result, is(true));
222 +
223 + result = peer1.peerFrameDecoder.receivedKeepaliveMessageLatch.await(
224 + MESSAGE_TIMEOUT_MS,
225 + TimeUnit.MILLISECONDS);
226 + assertThat(result, is(true));
227 + }
228 +
229 + @Test
230 + public void bgpOpenMessageTest7() throws InterruptedException {
231 + // Open message with both LS capability and as4 capability
232 + short afi = 16388;
233 + byte res = 0;
234 + byte safi = 71;
235 + peer1.peerChannelHandler.asNumber = 200;
236 + peer1.peerChannelHandler.version = 4;
237 + peer1.peerChannelHandler.holdTime = 120;
238 +
239 + peer1.peerChannelHandler.isLargeAsCapabilitySet = true;
240 + bgpControllerImpl.getConfig().setLargeASCapability(true);
241 + BGPValueType tempTlv = new FourOctetAsNumCapabilityTlv(200);
242 + peer1.peerChannelHandler.capabilityTlv.add(tempTlv);
243 +
244 + bgpControllerImpl.getConfig().setLsCapability(true);
245 + BGPValueType tempTlv1 = new MultiProtocolExtnCapabilityTlv(afi, res, safi);
246 + peer1.peerChannelHandler.capabilityTlv.add(tempTlv1);
247 + peer1.connect(connectToSocket);
248 +
249 + boolean result;
250 + result = peer1.peerFrameDecoder.receivedOpenMessageLatch.await(
251 + MESSAGE_TIMEOUT_MS,
252 + TimeUnit.MILLISECONDS);
253 + assertThat(result, is(true));
254 + }
255 +
256 + /**
257 + * A class to capture the state for a BGP peer.
258 + */
259 + private final class BgpPeerTest {
260 + private ClientBootstrap peerBootstrap;
261 + private BgpPeerFrameDecoderTest peerFrameDecoder =
262 + new BgpPeerFrameDecoderTest();
263 + private BgpPeerChannelHandlerTest peerChannelHandler;
264 +
265 + private BgpPeerTest(byte version, short asNumber,
266 + short holdTime, int bgpId, boolean isLargeAsCapabilitySet,
267 + LinkedList<BGPValueType> capabilityTlv) {
268 + peerChannelHandler = new BgpPeerChannelHandlerTest(version,
269 + asNumber, holdTime, bgpId, isLargeAsCapabilitySet, capabilityTlv);
270 + }
271 +
272 + /**
273 + * Starts the BGP peer.
274 + *
275 + * @param connectToSocket the socket to connect to
276 + */
277 + private void connect(InetSocketAddress connectToSocket)
278 + throws InterruptedException {
279 +
280 + ChannelFactory channelFactory =
281 + new NioClientSocketChannelFactory(
282 + Executors.newCachedThreadPool(),
283 + Executors.newCachedThreadPool());
284 + ChannelPipelineFactory pipelineFactory = () -> {
285 + ChannelPipeline pipeline = Channels.pipeline();
286 + pipeline.addLast("BgpPeerFrameDecoderTest",
287 + peerFrameDecoder);
288 + pipeline.addLast("BgpPeerChannelHandlerTest",
289 + peerChannelHandler);
290 + return pipeline;
291 + };
292 +
293 + peerBootstrap = new ClientBootstrap(channelFactory);
294 + peerBootstrap.setOption("child.keepAlive", true);
295 + peerBootstrap.setOption("child.tcpNoDelay", true);
296 + peerBootstrap.setPipelineFactory(pipelineFactory);
297 + peerBootstrap.connect(connectToSocket);
298 + }
299 + }
300 +}
...\ No newline at end of file ...\ No newline at end of file
1 +/*
2 + * Copyright 2014-2015 Open Networking Laboratory
3 + *
4 + * 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
7 + *
8 + * 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.
15 + */
16 +package org.onosproject.bgp;
17 +
18 +import java.util.LinkedList;
19 +import java.util.concurrent.TimeUnit;
20 +
21 +import org.jboss.netty.buffer.ChannelBuffer;
22 +import org.jboss.netty.buffer.ChannelBuffers;
23 +import org.jboss.netty.channel.ChannelHandlerContext;
24 +import org.jboss.netty.channel.ChannelStateEvent;
25 +import org.jboss.netty.channel.SimpleChannelHandler;
26 +import org.onosproject.bgpio.protocol.ver4.BGPKeepaliveMsgVer4;
27 +import org.onosproject.bgpio.protocol.ver4.BGPOpenMsgVer4;
28 +import org.onosproject.bgpio.types.BGPHeader;
29 +import org.onosproject.bgpio.types.BGPValueType;
30 +
31 +public class BgpPeerChannelHandlerTest extends SimpleChannelHandler {
32 + public static final int OPEN_MSG_MINIMUM_LENGTH = 29;
33 + public static final byte[] MARKER = new byte[] {(byte) 0xff, (byte) 0xff,
34 + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
35 + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
36 + (byte) 0xff, (byte) 0xff};
37 + public static final BGPHeader DEFAULT_OPEN_HEADER = new BGPHeader(MARKER,
38 + (short) OPEN_MSG_MINIMUM_LENGTH, (byte) 0X01);
39 + LinkedList<BGPValueType> capabilityTlv = new LinkedList<>();
40 + public byte version;
41 + public short asNumber;
42 + public short holdTime;
43 + public int bgpId;
44 + public boolean isLargeAsCapabilitySet;
45 +
46 + final BGPOpenMsgVer4 openMessage = new BGPOpenMsgVer4();
47 + ChannelHandlerContext savedCtx;
48 +
49 + /**
50 + * Constructor to initialize all variables of BGP Open message.
51 + *
52 + * @param version BGP version in open message
53 + * @param asNumber AS number in open message
54 + * @param holdTime hold time in open message
55 + * @param bgpId BGP identifier in open message
56 + * @param capabilityTlv capabilities in open message
57 + */
58 + public BgpPeerChannelHandlerTest(byte version,
59 + short asNumber,
60 + short holdTime,
61 + int bgpId,
62 + boolean isLargeAsCapabilitySet,
63 + LinkedList<BGPValueType> capabilityTlv) {
64 + this.version = version;
65 + this.asNumber = asNumber;
66 + this.holdTime = holdTime;
67 + this.bgpId = bgpId;
68 + this.isLargeAsCapabilitySet = isLargeAsCapabilitySet;
69 + this.capabilityTlv = capabilityTlv;
70 + }
71 +
72 + /**
73 + * closes the channel.
74 + */
75 + void closeChannel() {
76 + savedCtx.getChannel().close();
77 + }
78 +
79 + @Override
80 + public void channelConnected(ChannelHandlerContext ctx,
81 + ChannelStateEvent channelEvent) throws InterruptedException {
82 + this.savedCtx = ctx;
83 +
84 + BGPOpenMsgVer4 openMsg = new BGPOpenMsgVer4(DEFAULT_OPEN_HEADER,
85 + this.version,
86 + this.asNumber,
87 + this.holdTime,
88 + this.bgpId,
89 + this.capabilityTlv);
90 + ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
91 + openMsg.writeTo(buffer);
92 + ctx.getChannel().write(buffer);
93 +
94 + TimeUnit.MILLISECONDS.sleep(100);
95 +
96 + BGPKeepaliveMsgVer4 keepaliveMsg = new BGPKeepaliveMsgVer4();
97 + ChannelBuffer buffer1 = ChannelBuffers.dynamicBuffer();
98 + keepaliveMsg.writeTo(buffer1);
99 + ctx.getChannel().write(buffer1);
100 + }
101 +
102 + @Override
103 + public void channelDisconnected(ChannelHandlerContext ctx,
104 + ChannelStateEvent channelEvent) {
105 + //Do Nothing
106 + }
107 +}
1 +/*
2 + * Copyright 2014-2015 Open Networking Laboratory
3 + *
4 + * 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
7 + *
8 + * 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.
15 + */
16 +package org.onosproject.bgp;
17 +
18 +import org.jboss.netty.buffer.ChannelBuffer;
19 +import org.jboss.netty.channel.Channel;
20 +import org.jboss.netty.channel.ChannelHandlerContext;
21 +import org.jboss.netty.handler.codec.frame.FrameDecoder;
22 +import org.slf4j.Logger;
23 +import org.slf4j.LoggerFactory;
24 +import java.util.concurrent.CountDownLatch;
25 +
26 +/**
27 + * Class to decode the message received.
28 + */
29 +public class BgpPeerFrameDecoderTest extends FrameDecoder {
30 + static final byte OPEN_MSG_TYPE = 0x1;
31 + static final byte KEEPALIVE_MSG_TYPE = 0x4;
32 + static final byte UPDATE_MSG_TYPE = 0x2;
33 + static final byte NOTIFICATION_MSG_TYPE = 0x3;
34 + static final int MINIMUM_COMMON_HEADER_LENGTH = 19;
35 + static final int MINIMUM_OPEN_MSG_LENGTH = 29;
36 + static final int MINIMUM_HEADER_MARKER_LENGTH = 16;
37 + static final int HEADER_AND_MSG_LEN = 18;
38 +
39 + protected static final Logger log = LoggerFactory
40 + .getLogger(BgpPeerFrameDecoderTest.class);
41 + final CountDownLatch receivedOpenMessageLatch = new CountDownLatch(1);
42 + final CountDownLatch receivedKeepaliveMessageLatch = new CountDownLatch(1);
43 + final CountDownLatch receivedNotificationMessageLatch = new CountDownLatch(1);
44 +
45 + @Override
46 + protected Object decode(ChannelHandlerContext ctx,
47 + Channel channel,
48 + ChannelBuffer cb) throws Exception {
49 +
50 + if (cb.readableBytes() < MINIMUM_COMMON_HEADER_LENGTH) {
51 + log.debug("Error: Packet length is less then minimum length");
52 + return null;
53 + }
54 +
55 + byte[] marker = new byte[MINIMUM_HEADER_MARKER_LENGTH];
56 + cb.readBytes(marker);
57 + for (int i = 0; i < marker.length; i++) {
58 + if (marker[i] != (byte) 0xff) {
59 + log.debug("Error: Marker must be set all ones");
60 + ctx.getChannel().close();
61 + return null;
62 + }
63 + }
64 +
65 + short length = cb.readShort();
66 + if (length < MINIMUM_COMMON_HEADER_LENGTH) {
67 + log.debug("Error: Bad message length");
68 + ctx.getChannel().close();
69 + return null;
70 + }
71 +
72 + if (length != (cb.readableBytes() + HEADER_AND_MSG_LEN)) {
73 + log.debug("Error: Bad message length");
74 + ctx.getChannel().close();
75 + return null;
76 + }
77 +
78 + byte type = cb.readByte();
79 + int len = length - MINIMUM_COMMON_HEADER_LENGTH;
80 +
81 + ChannelBuffer message = cb.readBytes(len);
82 +
83 + switch (type) {
84 + case OPEN_MSG_TYPE:
85 + processBgpOpen(ctx, message);
86 + break;
87 + case UPDATE_MSG_TYPE:
88 + break;
89 + case NOTIFICATION_MSG_TYPE:
90 + processBgpNotification(ctx, message);
91 + break;
92 + case KEEPALIVE_MSG_TYPE:
93 + processBgpKeepalive(ctx, message);
94 + break;
95 + default:
96 + ctx.getChannel().close();
97 + return null;
98 + }
99 +
100 + return null;
101 + }
102 +
103 + /**
104 + * Processes BGP open message.
105 + *
106 + * @param ctx Channel handler context
107 + * @param message open message
108 + */
109 + private void processBgpOpen(ChannelHandlerContext ctx,
110 + ChannelBuffer message) {
111 + int minLength =
112 + MINIMUM_OPEN_MSG_LENGTH - MINIMUM_COMMON_HEADER_LENGTH;
113 + if (message.readableBytes() < minLength) {
114 + log.debug("Error: Bad message length");
115 + ctx.getChannel().close();
116 + return;
117 + }
118 +
119 + message.readByte(); // read version
120 + message.readShort(); // read AS number
121 + message.readShort(); // read Hold timer
122 + message.readInt(); // read BGP Identifier
123 + // Optional Parameters
124 + int optParamLen = message.readUnsignedByte();
125 + if (message.readableBytes() < optParamLen) {
126 + log.debug("Error: Bad message length");
127 + ctx.getChannel().close();
128 + return;
129 + }
130 + message.readBytes(optParamLen);
131 +
132 + // Open message received
133 + receivedOpenMessageLatch.countDown();
134 + }
135 +
136 + /**
137 + * Processes BGP keepalive message.
138 + *
139 + * @param ctx Channel handler context
140 + * @param message keepalive message
141 + */
142 + private void processBgpKeepalive(ChannelHandlerContext ctx,
143 + ChannelBuffer message) {
144 +
145 + // Keepalive message received
146 + receivedKeepaliveMessageLatch.countDown();
147 + }
148 +
149 + /**
150 + * Processes BGP notification message.
151 + *
152 + * @param ctx Channel handler context
153 + * @param message notification message
154 + */
155 + private void processBgpNotification(ChannelHandlerContext ctx,
156 + ChannelBuffer message) {
157 + byte[] data;
158 + message.readByte(); //read error code
159 + message.readByte(); // read error sub code
160 + if (message.readableBytes() > 0) {
161 + data = new byte[message.readableBytes()];
162 + message.readBytes(data, 0, message.readableBytes());
163 + }
164 +
165 + // Notification message received
166 + receivedNotificationMessageLatch.countDown();
167 + }
168 +}
...\ No newline at end of file ...\ No newline at end of file