Committed by
Thomas Vachuska
[Emu] [ONOS-2596] BGP Open message parsing, encoding and decoding
Change-Id: I2847849aef78314dfa8f3be0c8f34715719a15f2
Showing
2 changed files
with
619 additions
and
0 deletions
1 | +/* | ||
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 | + */ | ||
16 | + | ||
17 | +package org.onosproject.bgpio.protocol; | ||
18 | + | ||
19 | +import java.util.LinkedList; | ||
20 | + | ||
21 | +import org.onosproject.bgpio.exceptions.BGPParseException; | ||
22 | +import org.onosproject.bgpio.types.BGPHeader; | ||
23 | +import org.onosproject.bgpio.types.BGPValueType; | ||
24 | + | ||
25 | +/** | ||
26 | + * Abstraction of an entity providing BGP Open Message. | ||
27 | + */ | ||
28 | +public interface BGPOpenMsg extends BGPMessage { | ||
29 | + | ||
30 | + @Override | ||
31 | + BGPHeader getHeader(); | ||
32 | + | ||
33 | + @Override | ||
34 | + BGPVersion getVersion(); | ||
35 | + | ||
36 | + @Override | ||
37 | + BGPType getType(); | ||
38 | + | ||
39 | + /** | ||
40 | + * Returns hold time of Open Message. | ||
41 | + * | ||
42 | + * @return hold time of Open Message | ||
43 | + */ | ||
44 | + short getHoldTime(); | ||
45 | + | ||
46 | + /** | ||
47 | + * Returns AS Number of Open Message. | ||
48 | + * | ||
49 | + * @return AS Number of Open Message | ||
50 | + */ | ||
51 | + short getAsNumber(); | ||
52 | + | ||
53 | + /** | ||
54 | + * Returns BGP Identifier of Open Message. | ||
55 | + * | ||
56 | + * @return BGP Identifier of Open Message | ||
57 | + */ | ||
58 | + int getBgpId(); | ||
59 | + | ||
60 | + /** | ||
61 | + * Returns capabilities of Open Message. | ||
62 | + * | ||
63 | + * @return capabilities of Open Message | ||
64 | + */ | ||
65 | + LinkedList<BGPValueType> getCapabilityTlv(); | ||
66 | + | ||
67 | + /** | ||
68 | + * Builder interface with get and set functions to build Open message. | ||
69 | + */ | ||
70 | + interface Builder extends BGPMessage.Builder { | ||
71 | + | ||
72 | + @Override | ||
73 | + BGPOpenMsg build() throws BGPParseException; | ||
74 | + | ||
75 | + @Override | ||
76 | + BGPHeader getHeader(); | ||
77 | + | ||
78 | + @Override | ||
79 | + BGPVersion getVersion(); | ||
80 | + | ||
81 | + @Override | ||
82 | + BGPType getType(); | ||
83 | + | ||
84 | + /** | ||
85 | + * Returns hold time of Open Message. | ||
86 | + * | ||
87 | + * @return hold time of Open Message | ||
88 | + */ | ||
89 | + short getHoldTime(); | ||
90 | + | ||
91 | + /** | ||
92 | + * Sets hold time in Open Message and return its builder. | ||
93 | + * | ||
94 | + * @param holdtime | ||
95 | + * hold timer value in open message | ||
96 | + * @return builder by setting hold time | ||
97 | + */ | ||
98 | + Builder setHoldTime(short holdtime); | ||
99 | + | ||
100 | + /** | ||
101 | + * Returns as number of Open Message. | ||
102 | + * | ||
103 | + * @return as number of Open Message | ||
104 | + */ | ||
105 | + short getAsNumber(); | ||
106 | + | ||
107 | + /** | ||
108 | + * Sets AS number in Open Message and return its builder. | ||
109 | + * | ||
110 | + * @param asNumber | ||
111 | + * as number in open message | ||
112 | + * @return builder by setting asNumber | ||
113 | + */ | ||
114 | + Builder setAsNumber(short asNumber); | ||
115 | + | ||
116 | + /** | ||
117 | + * Returns BGP Identifier of Open Message. | ||
118 | + * | ||
119 | + * @return BGP Identifier of Open Message | ||
120 | + */ | ||
121 | + int getBgpId(); | ||
122 | + | ||
123 | + /** | ||
124 | + * Sets BGP Identifier in Open Message and return its builder. | ||
125 | + * | ||
126 | + * @param bgpId | ||
127 | + * BGP Identifier in open message | ||
128 | + * @return builder by setting BGP Identifier | ||
129 | + */ | ||
130 | + Builder setBgpId(int bgpId); | ||
131 | + | ||
132 | + /** | ||
133 | + * Returns capabilities of Open Message. | ||
134 | + * | ||
135 | + * @return capabilities of Open Message | ||
136 | + */ | ||
137 | + LinkedList<BGPValueType> getCapabilityTlv(); | ||
138 | + | ||
139 | + /** | ||
140 | + * Sets capabilities in Open Message and return its builder. | ||
141 | + * | ||
142 | + * @param capabilityTlv | ||
143 | + * capabilities in open message | ||
144 | + * @return builder by setting capabilities | ||
145 | + */ | ||
146 | + Builder setCapabilityTlv(LinkedList<BGPValueType> capabilityTlv); | ||
147 | + | ||
148 | + @Override | ||
149 | + Builder setHeader(BGPHeader bgpMsgHeader); | ||
150 | + } | ||
151 | +} |
1 | +/* | ||
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 | + */ | ||
16 | + | ||
17 | +package org.onosproject.bgpio.protocol.ver4; | ||
18 | + | ||
19 | +import java.util.LinkedList; | ||
20 | +import java.util.ListIterator; | ||
21 | + | ||
22 | +import org.jboss.netty.buffer.ChannelBuffer; | ||
23 | +import org.onosproject.bgpio.exceptions.BGPParseException; | ||
24 | +import org.onosproject.bgpio.protocol.BGPMessageReader; | ||
25 | +import org.onosproject.bgpio.protocol.BGPMessageWriter; | ||
26 | +import org.onosproject.bgpio.protocol.BGPOpenMsg; | ||
27 | +import org.onosproject.bgpio.protocol.BGPType; | ||
28 | +import org.onosproject.bgpio.protocol.BGPVersion; | ||
29 | +import org.onosproject.bgpio.types.BGPErrorType; | ||
30 | +import org.onosproject.bgpio.types.BGPHeader; | ||
31 | +import org.onosproject.bgpio.types.BGPValueType; | ||
32 | +import org.onosproject.bgpio.util.Validation; | ||
33 | +import org.slf4j.Logger; | ||
34 | +import org.slf4j.LoggerFactory; | ||
35 | + | ||
36 | +import com.google.common.base.MoreObjects; | ||
37 | + | ||
38 | +/** | ||
39 | + * Provides BGP open message. | ||
40 | + */ | ||
41 | +public class BGPOpenMsgVer4 implements BGPOpenMsg { | ||
42 | + | ||
43 | + /* | ||
44 | + 0 1 2 3 | ||
45 | + 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 | ||
46 | + +-+-+-+-+-+-+-+-+ | ||
47 | + | Version | | ||
48 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
49 | + | My Autonomous System | | ||
50 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
51 | + | Hold Time | | ||
52 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
53 | + | BGP Identifier | | ||
54 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
55 | + | Opt Parm Len | | ||
56 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
57 | + | Optional Parameters (variable) | | ||
58 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
59 | + OPEN Message Format | ||
60 | + REFERENCE : RFC 4271 | ||
61 | + */ | ||
62 | + | ||
63 | + protected static final Logger log = LoggerFactory.getLogger(BGPOpenMsgVer4.class); | ||
64 | + | ||
65 | + public static final byte PACKET_VERSION = 4; | ||
66 | + public static final int OPEN_MSG_MINIMUM_LENGTH = 10; | ||
67 | + public static final int MSG_HEADER_LENGTH = 19; | ||
68 | + public static final int MARKER_LENGTH = 16; | ||
69 | + public static final int DEFAULT_HOLD_TIME = 120; | ||
70 | + public static final int OPT_PARA_TYPE_CAPABILITY = 2; | ||
71 | + public static final BGPType MSG_TYPE = BGPType.OPEN; | ||
72 | + public static final byte[] MARKER = new byte[]{(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, | ||
73 | + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, | ||
74 | + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff}; | ||
75 | + public static final BGPHeader DEFAULT_OPEN_HEADER = new BGPHeader(MARKER, | ||
76 | + (short) OPEN_MSG_MINIMUM_LENGTH, (byte) 0X01); | ||
77 | + private BGPHeader bgpMsgHeader; | ||
78 | + private byte version; | ||
79 | + private short asNumber; | ||
80 | + private short holdTime; | ||
81 | + private int bgpId; | ||
82 | + private LinkedList<BGPValueType> capabilityTlv; | ||
83 | + | ||
84 | + public static final BGPOpenMsgVer4.Reader READER = new Reader(); | ||
85 | + | ||
86 | + /** | ||
87 | + * reset variables. | ||
88 | + */ | ||
89 | + public BGPOpenMsgVer4() { | ||
90 | + this.bgpMsgHeader = null; | ||
91 | + this.version = 0; | ||
92 | + this.holdTime = 0; | ||
93 | + this.asNumber = 0; | ||
94 | + this.bgpId = 0; | ||
95 | + this.capabilityTlv = null; | ||
96 | + } | ||
97 | + | ||
98 | + /** | ||
99 | + * Constructor to initialize all variables of BGP Open message. | ||
100 | + * | ||
101 | + * @param bgpMsgHeader | ||
102 | + * BGP Header in open message | ||
103 | + * @param version | ||
104 | + * BGP version in open message | ||
105 | + * @param holdTime | ||
106 | + * hold time in open message | ||
107 | + * @param asNumber | ||
108 | + * AS number in open message | ||
109 | + * @param bgpId | ||
110 | + * BGP identifier in open message | ||
111 | + * @param capabilityTlv | ||
112 | + * capabilities in open message | ||
113 | + */ | ||
114 | + public BGPOpenMsgVer4(BGPHeader bgpMsgHeader, byte version, short asNumber, short holdTime, | ||
115 | + int bgpId, LinkedList<BGPValueType> capabilityTlv) { | ||
116 | + this.bgpMsgHeader = bgpMsgHeader; | ||
117 | + this.version = version; | ||
118 | + this.asNumber = asNumber; | ||
119 | + this.holdTime = holdTime; | ||
120 | + this.bgpId = bgpId; | ||
121 | + this.capabilityTlv = capabilityTlv; | ||
122 | + } | ||
123 | + | ||
124 | + @Override | ||
125 | + public BGPHeader getHeader() { | ||
126 | + return this.bgpMsgHeader; | ||
127 | + } | ||
128 | + | ||
129 | + @Override | ||
130 | + public BGPVersion getVersion() { | ||
131 | + return BGPVersion.BGP_4; | ||
132 | + } | ||
133 | + | ||
134 | + @Override | ||
135 | + public BGPType getType() { | ||
136 | + return MSG_TYPE; | ||
137 | + } | ||
138 | + | ||
139 | + @Override | ||
140 | + public short getHoldTime() { | ||
141 | + return this.holdTime; | ||
142 | + } | ||
143 | + | ||
144 | + @Override | ||
145 | + public short getAsNumber() { | ||
146 | + return this.asNumber; | ||
147 | + } | ||
148 | + | ||
149 | + @Override | ||
150 | + public int getBgpId() { | ||
151 | + return this.bgpId; | ||
152 | + } | ||
153 | + | ||
154 | + @Override | ||
155 | + public LinkedList<BGPValueType> getCapabilityTlv() { | ||
156 | + return this.capabilityTlv; | ||
157 | + } | ||
158 | + | ||
159 | + /** | ||
160 | + * Reader class for reading BGP open message from channel buffer. | ||
161 | + */ | ||
162 | + public static class Reader implements BGPMessageReader<BGPOpenMsg> { | ||
163 | + | ||
164 | + @Override | ||
165 | + public BGPOpenMsg readFrom(ChannelBuffer cb, BGPHeader bgpHeader) throws BGPParseException { | ||
166 | + | ||
167 | + byte version; | ||
168 | + short holdTime; | ||
169 | + short asNumber; | ||
170 | + int bgpId; | ||
171 | + byte optParaLen = 0; | ||
172 | + byte optParaType; | ||
173 | + byte capParaLen = 0; | ||
174 | + LinkedList<BGPValueType> capabilityTlv = new LinkedList<>(); | ||
175 | + | ||
176 | + if (cb.readableBytes() < OPEN_MSG_MINIMUM_LENGTH) { | ||
177 | + log.error("[readFrom] Invalid length: Packet size is less than the minimum length "); | ||
178 | + Validation.validateLen(BGPErrorType.OPEN_MESSAGE_ERROR, BGPErrorType.BAD_MESSAGE_LENGTH, | ||
179 | + cb.readableBytes()); | ||
180 | + } | ||
181 | + | ||
182 | + // Read version | ||
183 | + version = cb.readByte(); | ||
184 | + if (version != PACKET_VERSION) { | ||
185 | + log.error("[readFrom] Invalid version: " + version); | ||
186 | + throw new BGPParseException(BGPErrorType.OPEN_MESSAGE_ERROR, | ||
187 | + BGPErrorType.UNSUPPORTED_VERSION_NUMBER, null); | ||
188 | + } | ||
189 | + | ||
190 | + // Read AS number | ||
191 | + asNumber = cb.readShort(); | ||
192 | + | ||
193 | + // Read Hold timer | ||
194 | + holdTime = cb.readShort(); | ||
195 | + | ||
196 | + // Read BGP Identifier | ||
197 | + bgpId = cb.readInt(); | ||
198 | + | ||
199 | + // Read optional parameter length | ||
200 | + optParaLen = cb.readByte(); | ||
201 | + | ||
202 | + // Read Capabilities if optional parameter length is greater than 0 | ||
203 | + if (optParaLen != 0) { | ||
204 | + // Read optional parameter type | ||
205 | + optParaType = cb.readByte(); | ||
206 | + | ||
207 | + // Read optional parameter length | ||
208 | + capParaLen = cb.readByte(); | ||
209 | + | ||
210 | + if (cb.readableBytes() < capParaLen) { | ||
211 | + throw new BGPParseException(BGPErrorType.OPEN_MESSAGE_ERROR, (byte) 0, null); | ||
212 | + } | ||
213 | + | ||
214 | + ChannelBuffer capaCb = cb.readBytes(capParaLen); | ||
215 | + | ||
216 | + // Parse capabilities only if optional parameter type is 2 | ||
217 | + if ((optParaType == OPT_PARA_TYPE_CAPABILITY) && (capParaLen != 0)) { | ||
218 | + capabilityTlv = parseCapabilityTlv(capaCb); | ||
219 | + } else { | ||
220 | + throw new BGPParseException(BGPErrorType.OPEN_MESSAGE_ERROR, | ||
221 | + BGPErrorType.UNSUPPORTED_OPTIONAL_PARAMETER, null); | ||
222 | + } | ||
223 | + } | ||
224 | + return new BGPOpenMsgVer4(bgpHeader, version, asNumber, holdTime, bgpId, capabilityTlv); | ||
225 | + } | ||
226 | + } | ||
227 | + | ||
228 | + /** | ||
229 | + * Parsing capabilities. | ||
230 | + * | ||
231 | + * @param cb of type channel buffer | ||
232 | + * @return capabilityTlv of open message | ||
233 | + * @throws BGPParseException while parsing capabilities | ||
234 | + */ | ||
235 | + protected static LinkedList<BGPValueType> parseCapabilityTlv(ChannelBuffer cb) throws BGPParseException { | ||
236 | + | ||
237 | + LinkedList<BGPValueType> capabilityTlv = new LinkedList<>(); | ||
238 | + | ||
239 | + // TODO: Capability parsing | ||
240 | + return capabilityTlv; | ||
241 | + } | ||
242 | + | ||
243 | + /** | ||
244 | + * Builder class for BGP open message. | ||
245 | + */ | ||
246 | + static class Builder implements BGPOpenMsg.Builder { | ||
247 | + | ||
248 | + private boolean isHeaderSet = false; | ||
249 | + private BGPHeader bgpMsgHeader; | ||
250 | + private boolean isHoldTimeSet = false; | ||
251 | + private short holdTime; | ||
252 | + private boolean isAsNumSet = false; | ||
253 | + private short asNumber; | ||
254 | + private boolean isBgpIdSet = false; | ||
255 | + private int bgpId; | ||
256 | + | ||
257 | + LinkedList<BGPValueType> capabilityTlv = new LinkedList<>(); | ||
258 | + | ||
259 | + @Override | ||
260 | + public BGPOpenMsg build() throws BGPParseException { | ||
261 | + BGPHeader bgpMsgHeader = this.isHeaderSet ? this.bgpMsgHeader : DEFAULT_OPEN_HEADER; | ||
262 | + short holdTime = this.isHoldTimeSet ? this.holdTime : DEFAULT_HOLD_TIME; | ||
263 | + | ||
264 | + if (!this.isAsNumSet) { | ||
265 | + throw new BGPParseException("BGP AS number is not set (mandatory)"); | ||
266 | + } | ||
267 | + | ||
268 | + if (!this.isBgpIdSet) { | ||
269 | + throw new BGPParseException("BGPID is not set (mandatory)"); | ||
270 | + } | ||
271 | + | ||
272 | + // TODO: capabilities build | ||
273 | + | ||
274 | + return new BGPOpenMsgVer4(bgpMsgHeader, PACKET_VERSION, this.asNumber, holdTime, this.bgpId, | ||
275 | + this.capabilityTlv); | ||
276 | + } | ||
277 | + | ||
278 | + @Override | ||
279 | + public BGPHeader getHeader() { | ||
280 | + return this.bgpMsgHeader; | ||
281 | + } | ||
282 | + | ||
283 | + @Override | ||
284 | + public Builder setHeader(BGPHeader bgpMsgHeader) { | ||
285 | + this.bgpMsgHeader = bgpMsgHeader; | ||
286 | + return this; | ||
287 | + } | ||
288 | + | ||
289 | + @Override | ||
290 | + public BGPVersion getVersion() { | ||
291 | + return BGPVersion.BGP_4; | ||
292 | + } | ||
293 | + | ||
294 | + @Override | ||
295 | + public BGPType getType() { | ||
296 | + return MSG_TYPE; | ||
297 | + } | ||
298 | + | ||
299 | + @Override | ||
300 | + public short getHoldTime() { | ||
301 | + return this.holdTime; | ||
302 | + } | ||
303 | + | ||
304 | + @Override | ||
305 | + public short getAsNumber() { | ||
306 | + return this.asNumber; | ||
307 | + } | ||
308 | + | ||
309 | + @Override | ||
310 | + public int getBgpId() { | ||
311 | + return this.bgpId; | ||
312 | + } | ||
313 | + | ||
314 | + @Override | ||
315 | + public LinkedList<BGPValueType> getCapabilityTlv() { | ||
316 | + return this.capabilityTlv; | ||
317 | + } | ||
318 | + | ||
319 | + @Override | ||
320 | + public Builder setHoldTime(short holdTime) { | ||
321 | + this.holdTime = holdTime; | ||
322 | + this.isHoldTimeSet = true; | ||
323 | + return this; | ||
324 | + } | ||
325 | + | ||
326 | + @Override | ||
327 | + public Builder setAsNumber(short asNumber) { | ||
328 | + this.asNumber = asNumber; | ||
329 | + this.isAsNumSet = true; | ||
330 | + return this; | ||
331 | + } | ||
332 | + | ||
333 | + @Override | ||
334 | + public Builder setBgpId(int bgpId) { | ||
335 | + this.bgpId = bgpId; | ||
336 | + this.isBgpIdSet = true; | ||
337 | + return this; | ||
338 | + } | ||
339 | + | ||
340 | + @Override | ||
341 | + public Builder setCapabilityTlv(LinkedList<BGPValueType> capabilityTlv) { | ||
342 | + this.capabilityTlv = capabilityTlv; | ||
343 | + return this; | ||
344 | + } | ||
345 | + } | ||
346 | + | ||
347 | + @Override | ||
348 | + public void writeTo(ChannelBuffer cb) { | ||
349 | + try { | ||
350 | + WRITER.write(cb, this); | ||
351 | + } catch (BGPParseException e) { | ||
352 | + log.debug("[writeTo] Error: " + e.toString()); | ||
353 | + } | ||
354 | + } | ||
355 | + | ||
356 | + public static final Writer WRITER = new Writer(); | ||
357 | + | ||
358 | + /** | ||
359 | + * Writer class for writing BGP open message to channel buffer. | ||
360 | + */ | ||
361 | + public static class Writer implements BGPMessageWriter<BGPOpenMsgVer4> { | ||
362 | + | ||
363 | + @Override | ||
364 | + public void write(ChannelBuffer cb, BGPOpenMsgVer4 message) throws BGPParseException { | ||
365 | + | ||
366 | + int optParaLen = 0; | ||
367 | + | ||
368 | + int startIndex = cb.writerIndex(); | ||
369 | + | ||
370 | + // write common header and get msg length index | ||
371 | + int msgLenIndex = message.bgpMsgHeader.write(cb); | ||
372 | + | ||
373 | + if (msgLenIndex <= 0) { | ||
374 | + throw new BGPParseException("Unable to write message header."); | ||
375 | + } | ||
376 | + | ||
377 | + // write version in 1-octet | ||
378 | + cb.writeByte(message.version); | ||
379 | + | ||
380 | + // TODO : Write AS number based on capabilities | ||
381 | + cb.writeShort(message.asNumber); | ||
382 | + | ||
383 | + // write HoldTime in next 2-octet | ||
384 | + cb.writeShort(message.holdTime); | ||
385 | + | ||
386 | + // write BGP Identifier in next 4-octet | ||
387 | + cb.writeInt(message.bgpId); | ||
388 | + | ||
389 | + // store the index of Optional parameter length | ||
390 | + int optParaLenIndex = cb.writerIndex(); | ||
391 | + | ||
392 | + // set optional parameter length as 0 | ||
393 | + cb.writeByte(0); | ||
394 | + | ||
395 | + // Pack capability TLV | ||
396 | + optParaLen = message.packCapabilityTlv(cb, message); | ||
397 | + | ||
398 | + if (optParaLen != 0) { | ||
399 | + // Update optional parameter length | ||
400 | + cb.setByte(optParaLenIndex, (byte) (optParaLen + 2)); //+2 for optional parameter type. | ||
401 | + } | ||
402 | + | ||
403 | + // write OPEN Object Length | ||
404 | + int length = cb.writerIndex() - startIndex; | ||
405 | + cb.setShort(msgLenIndex, (short) length); | ||
406 | + message.bgpMsgHeader.setLength((short) length); | ||
407 | + } | ||
408 | + } | ||
409 | + | ||
410 | + /** | ||
411 | + * returns length of capability tlvs. | ||
412 | + * | ||
413 | + * @param cb of type channel buffer | ||
414 | + * @param message of type BGPOpenMsgVer4 | ||
415 | + * @return capParaLen of open message | ||
416 | + */ | ||
417 | + protected int packCapabilityTlv(ChannelBuffer cb, BGPOpenMsgVer4 message) { | ||
418 | + int startIndex = cb.writerIndex(); | ||
419 | + int capParaLen = 0; | ||
420 | + int capParaLenIndex = 0; | ||
421 | + | ||
422 | + LinkedList<BGPValueType> capabilityTlv = message.capabilityTlv; | ||
423 | + ListIterator<BGPValueType> listIterator = capabilityTlv.listIterator(); | ||
424 | + | ||
425 | + if (listIterator.hasNext()) { | ||
426 | + // Set optional parameter type as 2 | ||
427 | + cb.writeByte(OPT_PARA_TYPE_CAPABILITY); | ||
428 | + | ||
429 | + // Store the index of capability parameter length and update length at the end | ||
430 | + capParaLenIndex = cb.writerIndex(); | ||
431 | + | ||
432 | + // Set capability parameter length as 0 | ||
433 | + cb.writeByte(0); | ||
434 | + | ||
435 | + // Update the startIndex to know the length of capability tlv | ||
436 | + startIndex = cb.writerIndex(); | ||
437 | + } | ||
438 | + | ||
439 | + while (listIterator.hasNext()) { | ||
440 | + BGPValueType tlv = listIterator.next(); | ||
441 | + if (tlv == null) { | ||
442 | + log.debug("Warning: tlv is null from CapabilityTlv list"); | ||
443 | + continue; | ||
444 | + } | ||
445 | + tlv.write(cb); | ||
446 | + } | ||
447 | + | ||
448 | + capParaLen = cb.writerIndex() - startIndex; | ||
449 | + | ||
450 | + if (capParaLen != 0) { | ||
451 | + // Update capability parameter length | ||
452 | + cb.setByte(capParaLenIndex, (byte) capParaLen); | ||
453 | + } | ||
454 | + return capParaLen; | ||
455 | + } | ||
456 | + | ||
457 | + @Override | ||
458 | + public String toString() { | ||
459 | + return MoreObjects.toStringHelper(getClass()) | ||
460 | + .add("bgpMsgHeader", bgpMsgHeader) | ||
461 | + .add("version", version) | ||
462 | + .add("holdTime", holdTime) | ||
463 | + .add("asNumber", asNumber) | ||
464 | + .add("bgpId", bgpId) | ||
465 | + .add("capabilityTlv", capabilityTlv) | ||
466 | + .toString(); | ||
467 | + } | ||
468 | +} |
-
Please register or login to post a comment