blob: 359eec253d55ec252e1fd9888d422f9d2173af2a [file] [log] [blame]
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +05301/*
2 * Copyright 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 */
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +053016package org.onosproject.bgpio.protocol.ver4;
17
18import java.util.LinkedList;
19import java.util.ListIterator;
20
21import org.jboss.netty.buffer.ChannelBuffer;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053022import org.onosproject.bgpio.exceptions.BgpParseException;
23import org.onosproject.bgpio.protocol.BgpMessageReader;
24import org.onosproject.bgpio.protocol.BgpMessageWriter;
25import org.onosproject.bgpio.protocol.BgpOpenMsg;
26import org.onosproject.bgpio.protocol.BgpType;
27import org.onosproject.bgpio.protocol.BgpVersion;
28import org.onosproject.bgpio.types.BgpErrorType;
29import org.onosproject.bgpio.types.BgpHeader;
30import org.onosproject.bgpio.types.BgpValueType;
Vidyashree Ramaf49b22c2015-10-13 15:30:24 +053031import org.onosproject.bgpio.types.FourOctetAsNumCapabilityTlv;
32import org.onosproject.bgpio.types.MultiProtocolExtnCapabilityTlv;
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +053033import org.onosproject.bgpio.util.Validation;
34import org.slf4j.Logger;
35import org.slf4j.LoggerFactory;
36
37import com.google.common.base.MoreObjects;
38
39/**
40 * Provides BGP open message.
41 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053042public class BgpOpenMsgVer4 implements BgpOpenMsg {
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +053043
44 /*
45 0 1 2 3
46 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
47 +-+-+-+-+-+-+-+-+
48 | Version |
49 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
50 | My Autonomous System |
51 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
52 | Hold Time |
53 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
54 | BGP Identifier |
55 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
56 | Opt Parm Len |
57 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
58 | Optional Parameters (variable) |
59 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
60 OPEN Message Format
61 REFERENCE : RFC 4271
62 */
63
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053064 protected static final Logger log = LoggerFactory.getLogger(BgpOpenMsgVer4.class);
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +053065
66 public static final byte PACKET_VERSION = 4;
67 public static final int OPEN_MSG_MINIMUM_LENGTH = 10;
68 public static final int MSG_HEADER_LENGTH = 19;
69 public static final int MARKER_LENGTH = 16;
70 public static final int DEFAULT_HOLD_TIME = 120;
Vidyashree Ramaf49b22c2015-10-13 15:30:24 +053071 public static final short AS_TRANS = 23456;
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +053072 public static final int OPT_PARA_TYPE_CAPABILITY = 2;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053073 public static final BgpType MSG_TYPE = BgpType.OPEN;
Vidyashree Ramaf49b22c2015-10-13 15:30:24 +053074 public static final short AFI = 16388;
75 public static final byte SAFI = 71;
76 public static final byte RES = 0;
77 public static final int FOUR_OCTET_AS_NUM_CAPA_TYPE = 65;
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +053078 public static final byte[] MARKER = new byte[]{(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
79 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
80 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff};
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053081 public static final BgpHeader DEFAULT_OPEN_HEADER = new BgpHeader(MARKER,
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +053082 (short) OPEN_MSG_MINIMUM_LENGTH, (byte) 0X01);
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053083 private BgpHeader bgpMsgHeader;
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +053084 private byte version;
85 private short asNumber;
86 private short holdTime;
87 private int bgpId;
Vidyashree Ramaf49b22c2015-10-13 15:30:24 +053088 private boolean isLargeAsCapabilitySet;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053089 private LinkedList<BgpValueType> capabilityTlv;
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +053090
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053091 public static final BgpOpenMsgVer4.Reader READER = new Reader();
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +053092
93 /**
94 * reset variables.
95 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053096 public BgpOpenMsgVer4() {
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +053097 this.bgpMsgHeader = null;
98 this.version = 0;
99 this.holdTime = 0;
100 this.asNumber = 0;
101 this.bgpId = 0;
102 this.capabilityTlv = null;
103 }
104
105 /**
106 * Constructor to initialize all variables of BGP Open message.
107 *
Vidyashree Ramaf49b22c2015-10-13 15:30:24 +0530108 * @param bgpMsgHeader BGP Header in open message
109 * @param version BGP version in open message
110 * @param holdTime hold time in open message
111 * @param asNumber AS number in open message
112 * @param bgpId BGP identifier in open message
113 * @param capabilityTlv capabilities in open message
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +0530114 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530115 public BgpOpenMsgVer4(BgpHeader bgpMsgHeader, byte version, short asNumber, short holdTime,
116 int bgpId, LinkedList<BgpValueType> capabilityTlv) {
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +0530117 this.bgpMsgHeader = bgpMsgHeader;
118 this.version = version;
119 this.asNumber = asNumber;
120 this.holdTime = holdTime;
121 this.bgpId = bgpId;
122 this.capabilityTlv = capabilityTlv;
123 }
124
125 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530126 public BgpHeader getHeader() {
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +0530127 return this.bgpMsgHeader;
128 }
129
130 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530131 public BgpVersion getVersion() {
132 return BgpVersion.BGP_4;
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +0530133 }
134
135 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530136 public BgpType getType() {
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +0530137 return MSG_TYPE;
138 }
139
140 @Override
141 public short getHoldTime() {
142 return this.holdTime;
143 }
144
145 @Override
146 public short getAsNumber() {
147 return this.asNumber;
148 }
149
150 @Override
151 public int getBgpId() {
152 return this.bgpId;
153 }
154
155 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530156 public LinkedList<BgpValueType> getCapabilityTlv() {
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +0530157 return this.capabilityTlv;
158 }
159
160 /**
161 * Reader class for reading BGP open message from channel buffer.
162 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530163 public static class Reader implements BgpMessageReader<BgpOpenMsg> {
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +0530164
165 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530166 public BgpOpenMsg readFrom(ChannelBuffer cb, BgpHeader bgpHeader) throws BgpParseException {
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +0530167
168 byte version;
169 short holdTime;
170 short asNumber;
171 int bgpId;
172 byte optParaLen = 0;
173 byte optParaType;
174 byte capParaLen = 0;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530175 LinkedList<BgpValueType> capabilityTlv = new LinkedList<>();
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +0530176
177 if (cb.readableBytes() < OPEN_MSG_MINIMUM_LENGTH) {
178 log.error("[readFrom] Invalid length: Packet size is less than the minimum length ");
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530179 Validation.validateLen(BgpErrorType.OPEN_MESSAGE_ERROR, BgpErrorType.BAD_MESSAGE_LENGTH,
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +0530180 cb.readableBytes());
181 }
182
183 // Read version
184 version = cb.readByte();
185 if (version != PACKET_VERSION) {
186 log.error("[readFrom] Invalid version: " + version);
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530187 throw new BgpParseException(BgpErrorType.OPEN_MESSAGE_ERROR,
188 BgpErrorType.UNSUPPORTED_VERSION_NUMBER, null);
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +0530189 }
190
191 // Read AS number
192 asNumber = cb.readShort();
193
194 // Read Hold timer
195 holdTime = cb.readShort();
196
197 // Read BGP Identifier
198 bgpId = cb.readInt();
199
200 // Read optional parameter length
201 optParaLen = cb.readByte();
202
203 // Read Capabilities if optional parameter length is greater than 0
204 if (optParaLen != 0) {
205 // Read optional parameter type
206 optParaType = cb.readByte();
207
208 // Read optional parameter length
209 capParaLen = cb.readByte();
210
211 if (cb.readableBytes() < capParaLen) {
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530212 throw new BgpParseException(BgpErrorType.OPEN_MESSAGE_ERROR, (byte) 0, null);
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +0530213 }
214
215 ChannelBuffer capaCb = cb.readBytes(capParaLen);
216
217 // Parse capabilities only if optional parameter type is 2
218 if ((optParaType == OPT_PARA_TYPE_CAPABILITY) && (capParaLen != 0)) {
219 capabilityTlv = parseCapabilityTlv(capaCb);
220 } else {
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530221 throw new BgpParseException(BgpErrorType.OPEN_MESSAGE_ERROR,
222 BgpErrorType.UNSUPPORTED_OPTIONAL_PARAMETER, null);
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +0530223 }
224 }
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530225 return new BgpOpenMsgVer4(bgpHeader, version, asNumber, holdTime, bgpId, capabilityTlv);
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +0530226 }
227 }
228
229 /**
230 * Parsing capabilities.
231 *
232 * @param cb of type channel buffer
233 * @return capabilityTlv of open message
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530234 * @throws BgpParseException while parsing capabilities
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +0530235 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530236 protected static LinkedList<BgpValueType> parseCapabilityTlv(ChannelBuffer cb) throws BgpParseException {
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +0530237
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530238 LinkedList<BgpValueType> capabilityTlv = new LinkedList<>();
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +0530239
Vidyashree Ramaf49b22c2015-10-13 15:30:24 +0530240 while (cb.readableBytes() > 0) {
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530241 BgpValueType tlv;
Vidyashree Ramaf49b22c2015-10-13 15:30:24 +0530242 short type = cb.readByte();
243 short length = cb.readByte();
244
245 switch (type) {
246 case FourOctetAsNumCapabilityTlv.TYPE:
247 log.debug("FourOctetAsNumCapabilityTlv");
248 if (FourOctetAsNumCapabilityTlv.LENGTH != length) {
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530249 throw new BgpParseException("Invalid length received for FourOctetAsNumCapabilityTlv.");
Vidyashree Ramaf49b22c2015-10-13 15:30:24 +0530250 }
251 if (length > cb.readableBytes()) {
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530252 throw new BgpParseException("Four octet as num tlv length"
Vidyashree Ramaf49b22c2015-10-13 15:30:24 +0530253 + " is more than readableBytes.");
254 }
255 int as4Num = cb.readInt();
256 tlv = new FourOctetAsNumCapabilityTlv(as4Num);
257 break;
258 case MultiProtocolExtnCapabilityTlv.TYPE:
259 log.debug("MultiProtocolExtnCapabilityTlv");
260 if (MultiProtocolExtnCapabilityTlv.LENGTH != length) {
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530261 throw new BgpParseException("Invalid length received for MultiProtocolExtnCapabilityTlv.");
Vidyashree Ramaf49b22c2015-10-13 15:30:24 +0530262 }
263 if (length > cb.readableBytes()) {
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530264 throw new BgpParseException("BGP LS tlv length is more than readableBytes.");
Vidyashree Ramaf49b22c2015-10-13 15:30:24 +0530265 }
266 short afi = cb.readShort();
267 byte res = cb.readByte();
268 byte safi = cb.readByte();
269 tlv = new MultiProtocolExtnCapabilityTlv(afi, res, safi);
270 break;
271 default:
272 log.debug("Warning: Unsupported TLV: " + type);
273 cb.skipBytes(length);
274 continue;
275 }
276 capabilityTlv.add(tlv);
277 }
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +0530278 return capabilityTlv;
279 }
280
281 /**
282 * Builder class for BGP open message.
283 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530284 static class Builder implements BgpOpenMsg.Builder {
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +0530285
286 private boolean isHeaderSet = false;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530287 private BgpHeader bgpMsgHeader;
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +0530288 private boolean isHoldTimeSet = false;
Vidyashree Ramaf49b22c2015-10-13 15:30:24 +0530289 private short holdTime;
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +0530290 private boolean isAsNumSet = false;
291 private short asNumber;
292 private boolean isBgpIdSet = false;
293 private int bgpId;
Vidyashree Ramaf49b22c2015-10-13 15:30:24 +0530294 private boolean isLargeAsCapabilityTlvSet = false;
295 private boolean isLsCapabilityTlvSet = false;
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +0530296
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530297 LinkedList<BgpValueType> capabilityTlv = new LinkedList<>();
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +0530298
299 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530300 public BgpOpenMsg build() throws BgpParseException {
301 BgpHeader bgpMsgHeader = this.isHeaderSet ? this.bgpMsgHeader : DEFAULT_OPEN_HEADER;
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +0530302 short holdTime = this.isHoldTimeSet ? this.holdTime : DEFAULT_HOLD_TIME;
303
304 if (!this.isAsNumSet) {
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530305 throw new BgpParseException("BGP AS number is not set (mandatory)");
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +0530306 }
307
308 if (!this.isBgpIdSet) {
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530309 throw new BgpParseException("BGPID is not set (mandatory)");
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +0530310 }
311
Vidyashree Ramaf49b22c2015-10-13 15:30:24 +0530312 if (this.isLargeAsCapabilityTlvSet) {
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530313 BgpValueType tlv;
Vidyashree Ramaafbbff92015-11-02 14:45:17 +0530314 int value = this.asNumber;
315 tlv = new FourOctetAsNumCapabilityTlv(value);
Vidyashree Ramaf49b22c2015-10-13 15:30:24 +0530316 this.capabilityTlv.add(tlv);
317 }
318
319 if (this.isLsCapabilityTlvSet) {
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530320 BgpValueType tlv;
Vidyashree Ramaf49b22c2015-10-13 15:30:24 +0530321 tlv = new MultiProtocolExtnCapabilityTlv(AFI, RES, SAFI);
322 this.capabilityTlv.add(tlv);
323 }
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +0530324
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530325 return new BgpOpenMsgVer4(bgpMsgHeader, PACKET_VERSION, this.asNumber, holdTime, this.bgpId,
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +0530326 this.capabilityTlv);
327 }
328
329 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530330 public Builder setHeader(BgpHeader bgpMsgHeader) {
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +0530331 this.bgpMsgHeader = bgpMsgHeader;
332 return this;
333 }
334
335 @Override
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +0530336 public Builder setHoldTime(short holdTime) {
337 this.holdTime = holdTime;
338 this.isHoldTimeSet = true;
339 return this;
340 }
341
342 @Override
343 public Builder setAsNumber(short asNumber) {
344 this.asNumber = asNumber;
345 this.isAsNumSet = true;
346 return this;
347 }
348
349 @Override
350 public Builder setBgpId(int bgpId) {
351 this.bgpId = bgpId;
352 this.isBgpIdSet = true;
353 return this;
354 }
355
356 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530357 public Builder setCapabilityTlv(LinkedList<BgpValueType> capabilityTlv) {
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +0530358 this.capabilityTlv = capabilityTlv;
359 return this;
360 }
Vidyashree Ramaf49b22c2015-10-13 15:30:24 +0530361
362 @Override
363 public Builder setLargeAsCapabilityTlv(boolean isLargeAsCapabilitySet) {
364 this.isLargeAsCapabilityTlvSet = isLargeAsCapabilitySet;
365 return this;
366 }
367
368 @Override
369 public Builder setLsCapabilityTlv(boolean isLsCapabilitySet) {
370 this.isLsCapabilityTlvSet = isLsCapabilitySet;
371 return this;
372 }
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +0530373 }
374
375 @Override
376 public void writeTo(ChannelBuffer cb) {
377 try {
378 WRITER.write(cb, this);
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530379 } catch (BgpParseException e) {
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +0530380 log.debug("[writeTo] Error: " + e.toString());
381 }
382 }
383
384 public static final Writer WRITER = new Writer();
385
386 /**
387 * Writer class for writing BGP open message to channel buffer.
388 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530389 public static class Writer implements BgpMessageWriter<BgpOpenMsgVer4> {
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +0530390
391 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530392 public void write(ChannelBuffer cb, BgpOpenMsgVer4 message) throws BgpParseException {
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +0530393
394 int optParaLen = 0;
Vidyashree Ramaf49b22c2015-10-13 15:30:24 +0530395 int as4num = 0;
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +0530396
397 int startIndex = cb.writerIndex();
398
399 // write common header and get msg length index
400 int msgLenIndex = message.bgpMsgHeader.write(cb);
401
402 if (msgLenIndex <= 0) {
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530403 throw new BgpParseException("Unable to write message header.");
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +0530404 }
405
406 // write version in 1-octet
407 cb.writeByte(message.version);
408
Vidyashree Ramaf49b22c2015-10-13 15:30:24 +0530409 // get as4num if LS Capability is set
410 if (message.isLargeAsCapabilitySet) {
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530411 LinkedList<BgpValueType> capabilityTlv = message
Vidyashree Ramaf49b22c2015-10-13 15:30:24 +0530412 .getCapabilityTlv();
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530413 ListIterator<BgpValueType> listIterator = capabilityTlv
Vidyashree Ramaf49b22c2015-10-13 15:30:24 +0530414 .listIterator();
415
416 while (listIterator.hasNext()) {
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530417 BgpValueType tlv = listIterator.next();
Vidyashree Ramaf49b22c2015-10-13 15:30:24 +0530418 if (tlv.getType() == FOUR_OCTET_AS_NUM_CAPA_TYPE) {
419 as4num = ((FourOctetAsNumCapabilityTlv) tlv).getInt();
420 break;
421 }
422 }
423 }
424
425 if ((message.isLargeAsCapabilitySet) && (as4num > 65535)) {
426 // write As number as AS_TRANS
427 cb.writeShort(AS_TRANS);
428 } else {
429 // write AS number in next 2-octet
430 cb.writeShort(message.asNumber);
431 }
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +0530432
433 // write HoldTime in next 2-octet
434 cb.writeShort(message.holdTime);
435
436 // write BGP Identifier in next 4-octet
437 cb.writeInt(message.bgpId);
438
439 // store the index of Optional parameter length
440 int optParaLenIndex = cb.writerIndex();
441
442 // set optional parameter length as 0
443 cb.writeByte(0);
444
445 // Pack capability TLV
446 optParaLen = message.packCapabilityTlv(cb, message);
447
448 if (optParaLen != 0) {
449 // Update optional parameter length
450 cb.setByte(optParaLenIndex, (byte) (optParaLen + 2)); //+2 for optional parameter type.
451 }
452
453 // write OPEN Object Length
454 int length = cb.writerIndex() - startIndex;
455 cb.setShort(msgLenIndex, (short) length);
456 message.bgpMsgHeader.setLength((short) length);
457 }
458 }
459
460 /**
461 * returns length of capability tlvs.
462 *
463 * @param cb of type channel buffer
464 * @param message of type BGPOpenMsgVer4
465 * @return capParaLen of open message
466 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530467 protected int packCapabilityTlv(ChannelBuffer cb, BgpOpenMsgVer4 message) {
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +0530468 int startIndex = cb.writerIndex();
469 int capParaLen = 0;
470 int capParaLenIndex = 0;
471
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530472 LinkedList<BgpValueType> capabilityTlv = message.capabilityTlv;
473 ListIterator<BgpValueType> listIterator = capabilityTlv.listIterator();
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +0530474
475 if (listIterator.hasNext()) {
476 // Set optional parameter type as 2
477 cb.writeByte(OPT_PARA_TYPE_CAPABILITY);
478
479 // Store the index of capability parameter length and update length at the end
480 capParaLenIndex = cb.writerIndex();
481
482 // Set capability parameter length as 0
483 cb.writeByte(0);
484
485 // Update the startIndex to know the length of capability tlv
486 startIndex = cb.writerIndex();
487 }
488
489 while (listIterator.hasNext()) {
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530490 BgpValueType tlv = listIterator.next();
Vidyashree Rama6d4f84e2015-09-21 20:01:02 +0530491 if (tlv == null) {
492 log.debug("Warning: tlv is null from CapabilityTlv list");
493 continue;
494 }
495 tlv.write(cb);
496 }
497
498 capParaLen = cb.writerIndex() - startIndex;
499
500 if (capParaLen != 0) {
501 // Update capability parameter length
502 cb.setByte(capParaLenIndex, (byte) capParaLen);
503 }
504 return capParaLen;
505 }
506
507 @Override
508 public String toString() {
509 return MoreObjects.toStringHelper(getClass())
510 .add("bgpMsgHeader", bgpMsgHeader)
511 .add("version", version)
512 .add("holdTime", holdTime)
513 .add("asNumber", asNumber)
514 .add("bgpId", bgpId)
515 .add("capabilityTlv", capabilityTlv)
516 .toString();
517 }
518}