Shashikanth VH
Committed by Gerrit Code Review

[ONOS-3857] BGP flow spec NLRI encoding for MP_REACH and MP_UNREACH.

Change-Id: I44237a12c4235fda2fcfafe60c3935159dae5231
...@@ -19,11 +19,14 @@ package org.onosproject.bgpio.types; ...@@ -19,11 +19,14 @@ package org.onosproject.bgpio.types;
19 import java.net.InetAddress; 19 import java.net.InetAddress;
20 import java.util.LinkedList; 20 import java.util.LinkedList;
21 import java.util.List; 21 import java.util.List;
22 +import java.util.ListIterator;
22 23
23 import org.jboss.netty.buffer.ChannelBuffer; 24 import org.jboss.netty.buffer.ChannelBuffer;
25 +import org.jboss.netty.buffer.ChannelBuffers;
24 import org.onlab.packet.Ip4Address; 26 import org.onlab.packet.Ip4Address;
25 import org.onosproject.bgpio.exceptions.BgpParseException; 27 import org.onosproject.bgpio.exceptions.BgpParseException;
26 import org.onosproject.bgpio.protocol.BgpLSNlri; 28 import org.onosproject.bgpio.protocol.BgpLSNlri;
29 +import org.onosproject.bgpio.protocol.flowspec.BgpFlowSpecDetails;
27 import org.onosproject.bgpio.protocol.linkstate.BgpPrefixIPv4LSNlriVer4; 30 import org.onosproject.bgpio.protocol.linkstate.BgpPrefixIPv4LSNlriVer4;
28 import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSNlriVer4; 31 import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSNlriVer4;
29 import org.onosproject.bgpio.protocol.linkstate.BgpLinkLsNlriVer4; 32 import org.onosproject.bgpio.protocol.linkstate.BgpLinkLsNlriVer4;
...@@ -42,13 +45,15 @@ public class MpReachNlri implements BgpValueType { ...@@ -42,13 +45,15 @@ public class MpReachNlri implements BgpValueType {
42 private static final Logger log = LoggerFactory.getLogger(MpReachNlri.class); 45 private static final Logger log = LoggerFactory.getLogger(MpReachNlri.class);
43 public static final byte MPREACHNLRI_TYPE = 14; 46 public static final byte MPREACHNLRI_TYPE = 14;
44 public static final byte LINK_NLRITYPE = 2; 47 public static final byte LINK_NLRITYPE = 2;
45 - 48 + public static final byte FLAGS = (byte) 0x90;
49 + public static final short FLOW_SPEC_LEN = 240;
46 private boolean isMpReachNlri = false; 50 private boolean isMpReachNlri = false;
47 private final List<BgpLSNlri> mpReachNlri; 51 private final List<BgpLSNlri> mpReachNlri;
48 private final int length; 52 private final int length;
49 private final short afi; 53 private final short afi;
50 private final byte safi; 54 private final byte safi;
51 private final Ip4Address ipNextHop; 55 private final Ip4Address ipNextHop;
56 + private BgpFlowSpecDetails bgpFlowSpecInfo;
52 57
53 /** 58 /**
54 * Constructor to initialize parameters. 59 * Constructor to initialize parameters.
...@@ -68,6 +73,16 @@ public class MpReachNlri implements BgpValueType { ...@@ -68,6 +73,16 @@ public class MpReachNlri implements BgpValueType {
68 this.length = length; 73 this.length = length;
69 } 74 }
70 75
76 + public MpReachNlri(BgpFlowSpecDetails bgpFlowSpecInfo, short afi, byte safi) {
77 + this.mpReachNlri = null;
78 + this.isMpReachNlri = true;
79 + this.length = 0;
80 + this.ipNextHop = null;
81 + this.bgpFlowSpecInfo = bgpFlowSpecInfo;
82 + this.afi = afi;
83 + this.safi = safi;
84 + }
85 +
71 /** 86 /**
72 * Returns whether MpReachNlri is present. 87 * Returns whether MpReachNlri is present.
73 * 88 *
...@@ -96,6 +111,15 @@ public class MpReachNlri implements BgpValueType { ...@@ -96,6 +111,15 @@ public class MpReachNlri implements BgpValueType {
96 } 111 }
97 112
98 /** 113 /**
114 + * Returns BGP flow specification info.
115 + *
116 + * @return BGP flow specification info
117 + */
118 + public BgpFlowSpecDetails bgpFlowSpecInfo() {
119 + return this.bgpFlowSpecInfo;
120 + }
121 +
122 + /**
99 * Reads from ChannelBuffer and parses MpReachNlri. 123 * Reads from ChannelBuffer and parses MpReachNlri.
100 * 124 *
101 * @param cb channelBuffer 125 * @param cb channelBuffer
...@@ -161,6 +185,79 @@ public class MpReachNlri implements BgpValueType { ...@@ -161,6 +185,79 @@ public class MpReachNlri implements BgpValueType {
161 } 185 }
162 mpReachNlri.add(bgpLSNlri); 186 mpReachNlri.add(bgpLSNlri);
163 } 187 }
188 + } else if ((afi == Constants.AFI_FLOWSPEC_VALUE)
189 + && ((safi == Constants.SAFI_FLOWSPEC_VALUE)
190 + || (safi == Constants.VPN_SAFI_FLOWSPEC_VALUE))) {
191 + List<BgpValueType> flowSpecComponents = new LinkedList<>();
192 + BgpValueType flowSpecComponent = null;
193 +
194 + byte nextHopLen = tempCb.readByte();
195 + if (nextHopLen > 0) {
196 + InetAddress ipAddress = Validation.toInetAddress(nextHopLen, tempCb);
197 + if (ipAddress.isMulticastAddress()) {
198 + throw new BgpParseException("Multicast not supported");
199 + }
200 + ipNextHop = Ip4Address.valueOf(ipAddress);
201 + }
202 +
203 + byte reserved = tempCb.readByte();
204 + short totNlriLen = tempCb.getByte(tempCb.readerIndex());
205 + if (totNlriLen >= FLOW_SPEC_LEN) {
206 + totNlriLen = tempCb.readShort();
207 + } else {
208 + totNlriLen = tempCb.readByte();
209 + }
210 + if (tempCb.readableBytes() < totNlriLen) {
211 + Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR,
212 + BgpErrorType.ATTRIBUTE_LENGTH_ERROR, totNlriLen);
213 + }
214 + tempBuf = tempCb.readBytes(totNlriLen);
215 + while (tempBuf.readableBytes() > 0) {
216 + short type = tempBuf.readByte();
217 + switch (type) {
218 + case Constants.BGP_FLOWSPEC_DST_PREFIX:
219 + flowSpecComponent = BgpFsDestinationPrefix.read(tempBuf);
220 + break;
221 + case Constants.BGP_FLOWSPEC_SRC_PREFIX:
222 + flowSpecComponent = BgpFsSourcePrefix.read(tempBuf);
223 + break;
224 + case Constants.BGP_FLOWSPEC_IP_PROTO:
225 + flowSpecComponent = BgpFsIpProtocol.read(tempBuf);
226 + break;
227 + case Constants.BGP_FLOWSPEC_PORT:
228 + flowSpecComponent = BgpFsPortNum.read(tempBuf);
229 + break;
230 + case Constants.BGP_FLOWSPEC_DST_PORT:
231 + flowSpecComponent = BgpFsDestinationPortNum.read(tempBuf);
232 + break;
233 + case Constants.BGP_FLOWSPEC_SRC_PORT:
234 + flowSpecComponent = BgpFsSourcePortNum.read(tempBuf);
235 + break;
236 + case Constants.BGP_FLOWSPEC_ICMP_TP:
237 + flowSpecComponent = BgpFsIcmpType.read(tempBuf);
238 + break;
239 + case Constants.BGP_FLOWSPEC_ICMP_CD:
240 + flowSpecComponent = BgpFsIcmpType.read(tempBuf);
241 + break;
242 + case Constants.BGP_FLOWSPEC_TCP_FLAGS:
243 + flowSpecComponent = BgpFsTcpFlags.read(tempBuf);
244 + break;
245 + case Constants.BGP_FLOWSPEC_PCK_LEN:
246 + flowSpecComponent = BgpFsPacketLength.read(tempBuf);
247 + break;
248 + case Constants.BGP_FLOWSPEC_DSCP:
249 + flowSpecComponent = BgpFsDscpValue.read(tempBuf);
250 + break;
251 + case Constants.BGP_FLOWSPEC_FRAGMENT:
252 + flowSpecComponent = BgpFsFragment.read(tempBuf);
253 + break;
254 + default:
255 + log.debug("flow spec type not supported" + type);
256 + break;
257 + }
258 + flowSpecComponents.add(flowSpecComponent);
259 + }
260 + return new MpReachNlri(new BgpFlowSpecDetails(flowSpecComponents), afi, safi);
164 } else { 261 } else {
165 throw new BgpParseException("Not Supporting afi " + afi + "safi " + safi); 262 throw new BgpParseException("Not Supporting afi " + afi + "safi " + safi);
166 } 263 }
...@@ -202,14 +299,114 @@ public class MpReachNlri implements BgpValueType { ...@@ -202,14 +299,114 @@ public class MpReachNlri implements BgpValueType {
202 299
203 @Override 300 @Override
204 public int write(ChannelBuffer cb) { 301 public int write(ChannelBuffer cb) {
205 - //Not to be Implemented as of now 302 + int iLenStartIndex = cb.writerIndex();
206 - return 0; 303 + if ((afi == Constants.AFI_FLOWSPEC_VALUE) && ((safi == Constants.SAFI_FLOWSPEC_VALUE)
304 + || (safi == Constants.VPN_SAFI_FLOWSPEC_VALUE))) {
305 +
306 + cb.writeByte(FLAGS);
307 + cb.writeByte(MPREACHNLRI_TYPE);
308 +
309 + int mpReachDataIndx = cb.writerIndex();
310 + cb.writeShort(0);
311 +
312 + cb.writeShort(afi);
313 + cb.writeByte(safi);
314 + //next hop address
315 + cb.writeByte(0);
316 + //sub network points of attachment
317 + cb.writeByte(0);
318 +
319 + if (bgpFlowSpecInfo.routeDistinguisher() != null) {
320 + cb.writeLong(bgpFlowSpecInfo.routeDistinguisher().getRouteDistinguisher());
321 + }
322 +
323 + ChannelBuffer flowSpecTmpBuff = ChannelBuffers.dynamicBuffer();
324 + int tmpBuffStartIndx = flowSpecTmpBuff.writerIndex();
325 +
326 + List<BgpValueType> flowSpec = bgpFlowSpecInfo.flowSpecComponents();
327 + ListIterator<BgpValueType> listIterator = flowSpec.listIterator();
328 +
329 + while (listIterator.hasNext()) {
330 + BgpValueType tlv = listIterator.next();
331 + switch (tlv.getType()) {
332 + case Constants.BGP_FLOWSPEC_DST_PREFIX:
333 + BgpFsDestinationPrefix fsDstPrefix = (BgpFsDestinationPrefix) tlv;
334 + fsDstPrefix.write(flowSpecTmpBuff);
335 + break;
336 + case Constants.BGP_FLOWSPEC_SRC_PREFIX:
337 + BgpFsSourcePrefix fsSrcPrefix = (BgpFsSourcePrefix) tlv;
338 + fsSrcPrefix.write(flowSpecTmpBuff);
339 + break;
340 + case Constants.BGP_FLOWSPEC_IP_PROTO:
341 + BgpFsIpProtocol fsIpProtocol = (BgpFsIpProtocol) tlv;
342 + fsIpProtocol.write(flowSpecTmpBuff);
343 + break;
344 + case Constants.BGP_FLOWSPEC_PORT:
345 + BgpFsPortNum fsPortNum = (BgpFsPortNum) tlv;
346 + fsPortNum.write(flowSpecTmpBuff);
347 + break;
348 + case Constants.BGP_FLOWSPEC_DST_PORT:
349 + BgpFsDestinationPortNum fsDstPortNum = (BgpFsDestinationPortNum) tlv;
350 + fsDstPortNum.write(flowSpecTmpBuff);
351 + break;
352 + case Constants.BGP_FLOWSPEC_SRC_PORT:
353 + BgpFsSourcePortNum fsSrcPortNum = (BgpFsSourcePortNum) tlv;
354 + fsSrcPortNum.write(flowSpecTmpBuff);
355 + break;
356 + case Constants.BGP_FLOWSPEC_ICMP_TP:
357 + BgpFsIcmpType fsIcmpType = (BgpFsIcmpType) tlv;
358 + fsIcmpType.write(flowSpecTmpBuff);
359 + break;
360 + case Constants.BGP_FLOWSPEC_ICMP_CD:
361 + BgpFsIcmpCode fsIcmpCode = (BgpFsIcmpCode) tlv;
362 + fsIcmpCode.write(flowSpecTmpBuff);
363 + break;
364 + case Constants.BGP_FLOWSPEC_TCP_FLAGS:
365 + BgpFsTcpFlags fsTcpFlags = (BgpFsTcpFlags) tlv;
366 + fsTcpFlags.write(flowSpecTmpBuff);
367 + break;
368 + case Constants.BGP_FLOWSPEC_PCK_LEN:
369 + BgpFsPacketLength fsPacketLen = (BgpFsPacketLength) tlv;
370 + fsPacketLen.write(flowSpecTmpBuff);
371 + break;
372 + case Constants.BGP_FLOWSPEC_DSCP:
373 + BgpFsDscpValue fsDscpVal = (BgpFsDscpValue) tlv;
374 + fsDscpVal.write(flowSpecTmpBuff);
375 + break;
376 + case Constants.BGP_FLOWSPEC_FRAGMENT:
377 + BgpFsFragment fsFragment = (BgpFsFragment) tlv;
378 + fsFragment.write(flowSpecTmpBuff);
379 + break;
380 + default:
381 + break;
382 + }
383 + }
384 +
385 + /* RFC 5575: section 4, If the NLRI length value is smaller than 240 (0xf0 hex), the length
386 + field can be encoded as a single octet. Otherwise, it is encoded as
387 + an extended-length 2-octet values */
388 + int len = flowSpecTmpBuff.writerIndex() - tmpBuffStartIndx;
389 + if (len >= FLOW_SPEC_LEN) {
390 + cb.writeShort(len);
391 + } else {
392 + cb.writeByte(len);
393 + }
394 + //Copy from bynamic buffer to channel buffer
395 + cb.writeBytes(flowSpecTmpBuff);
396 +
397 + int fsNlriLen = cb.writerIndex() - mpReachDataIndx;
398 + cb.setShort(mpReachDataIndx, (short) (fsNlriLen - 2));
399 +
400 + }
401 +
402 + return cb.writerIndex() - iLenStartIndex;
207 } 403 }
208 404
209 @Override 405 @Override
210 public String toString() { 406 public String toString() {
211 - return MoreObjects.toStringHelper(getClass()) 407 + return MoreObjects.toStringHelper(getClass()).omitNullValues()
212 .add("mpReachNlri", mpReachNlri) 408 .add("mpReachNlri", mpReachNlri)
409 + .add("bgpFlowSpecInfo", bgpFlowSpecInfo)
213 .add("afi", afi) 410 .add("afi", afi)
214 .add("safi", safi) 411 .add("safi", safi)
215 .add("ipNextHop", ipNextHop) 412 .add("ipNextHop", ipNextHop)
......
...@@ -18,10 +18,13 @@ package org.onosproject.bgpio.types; ...@@ -18,10 +18,13 @@ package org.onosproject.bgpio.types;
18 18
19 import java.util.LinkedList; 19 import java.util.LinkedList;
20 import java.util.List; 20 import java.util.List;
21 +import java.util.ListIterator;
21 22
22 import org.jboss.netty.buffer.ChannelBuffer; 23 import org.jboss.netty.buffer.ChannelBuffer;
24 +import org.jboss.netty.buffer.ChannelBuffers;
23 import org.onosproject.bgpio.exceptions.BgpParseException; 25 import org.onosproject.bgpio.exceptions.BgpParseException;
24 import org.onosproject.bgpio.protocol.BgpLSNlri; 26 import org.onosproject.bgpio.protocol.BgpLSNlri;
27 +import org.onosproject.bgpio.protocol.flowspec.BgpFlowSpecDetails;
25 import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSNlriVer4; 28 import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSNlriVer4;
26 import org.onosproject.bgpio.protocol.linkstate.BgpPrefixIPv4LSNlriVer4; 29 import org.onosproject.bgpio.protocol.linkstate.BgpPrefixIPv4LSNlriVer4;
27 import org.onosproject.bgpio.protocol.linkstate.BgpLinkLsNlriVer4; 30 import org.onosproject.bgpio.protocol.linkstate.BgpLinkLsNlriVer4;
...@@ -40,12 +43,14 @@ public class MpUnReachNlri implements BgpValueType { ...@@ -40,12 +43,14 @@ public class MpUnReachNlri implements BgpValueType {
40 private static final Logger log = LoggerFactory.getLogger(MpUnReachNlri.class); 43 private static final Logger log = LoggerFactory.getLogger(MpUnReachNlri.class);
41 public static final byte MPUNREACHNLRI_TYPE = 15; 44 public static final byte MPUNREACHNLRI_TYPE = 15;
42 public static final byte LINK_NLRITYPE = 2; 45 public static final byte LINK_NLRITYPE = 2;
43 - 46 + public static final byte FLAGS = (byte) 0x90;
47 + public static final short FLOW_SPEC_LEN = 240;
44 private boolean isMpUnReachNlri = false; 48 private boolean isMpUnReachNlri = false;
45 private final short afi; 49 private final short afi;
46 private final byte safi; 50 private final byte safi;
47 private final List<BgpLSNlri> mpUnReachNlri; 51 private final List<BgpLSNlri> mpUnReachNlri;
48 private final int length; 52 private final int length;
53 + private BgpFlowSpecDetails bgpFlowSpecInfo;
49 54
50 /** 55 /**
51 * Constructor to initialize parameters. 56 * Constructor to initialize parameters.
...@@ -64,6 +69,24 @@ public class MpUnReachNlri implements BgpValueType { ...@@ -64,6 +69,24 @@ public class MpUnReachNlri implements BgpValueType {
64 this.length = length; 69 this.length = length;
65 } 70 }
66 71
72 + public MpUnReachNlri(BgpFlowSpecDetails bgpFlowSpecInfo, short afi, byte safi) {
73 + this.mpUnReachNlri = null;
74 + this.isMpUnReachNlri = true;
75 + this.length = 0;
76 + this.bgpFlowSpecInfo = bgpFlowSpecInfo;
77 + this.afi = afi;
78 + this.safi = safi;
79 + }
80 +
81 + /**
82 + * Returns BGP flow specification info.
83 + *
84 + * @return BGP flow specification info
85 + */
86 + public BgpFlowSpecDetails bgpFlowSpecInfo() {
87 + return this.bgpFlowSpecInfo;
88 + }
89 +
67 /** 90 /**
68 * Reads from ChannelBuffer and parses MpUnReachNlri. 91 * Reads from ChannelBuffer and parses MpUnReachNlri.
69 * 92 *
...@@ -123,13 +146,76 @@ public class MpUnReachNlri implements BgpValueType { ...@@ -123,13 +146,76 @@ public class MpUnReachNlri implements BgpValueType {
123 break; 146 break;
124 default: 147 default:
125 log.debug("nlriType not supported" + nlriType); 148 log.debug("nlriType not supported" + nlriType);
149 + break;
126 } 150 }
127 mpUnReachNlri.add(bgpLSNlri); 151 mpUnReachNlri.add(bgpLSNlri);
128 } 152 }
153 + } else if ((afi == Constants.AFI_FLOWSPEC_VALUE)
154 + && ((safi == Constants.SAFI_FLOWSPEC_VALUE)
155 + || (safi == Constants.VPN_SAFI_FLOWSPEC_VALUE))) {
156 + List<BgpValueType> flowSpecComponents = new LinkedList<>();
157 + BgpValueType flowSpecComponent = null;
158 +
159 + short totNlriLen = tempCb.getByte(tempCb.readerIndex());
160 + if (totNlriLen >= FLOW_SPEC_LEN) {
161 + totNlriLen = tempCb.readShort();
162 + } else {
163 + totNlriLen = tempCb.readByte();
164 + }
165 + if (tempCb.readableBytes() < totNlriLen) {
166 + Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR,
167 + BgpErrorType.ATTRIBUTE_LENGTH_ERROR, totNlriLen);
168 + }
169 + tempBuf = tempCb.readBytes(totNlriLen);
170 + while (tempBuf.readableBytes() > 0) {
171 + short type = tempBuf.readByte();
172 + switch (type) {
173 + case Constants.BGP_FLOWSPEC_DST_PREFIX:
174 + flowSpecComponent = BgpFsDestinationPrefix.read(tempBuf);
175 + break;
176 + case Constants.BGP_FLOWSPEC_SRC_PREFIX:
177 + flowSpecComponent = BgpFsSourcePrefix.read(tempBuf);
178 + break;
179 + case Constants.BGP_FLOWSPEC_IP_PROTO:
180 + flowSpecComponent = BgpFsIpProtocol.read(tempBuf);
181 + break;
182 + case Constants.BGP_FLOWSPEC_PORT:
183 + flowSpecComponent = BgpFsPortNum.read(tempBuf);
184 + break;
185 + case Constants.BGP_FLOWSPEC_DST_PORT:
186 + flowSpecComponent = BgpFsDestinationPortNum.read(tempBuf);
187 + break;
188 + case Constants.BGP_FLOWSPEC_SRC_PORT:
189 + flowSpecComponent = BgpFsSourcePortNum.read(tempBuf);
190 + break;
191 + case Constants.BGP_FLOWSPEC_ICMP_TP:
192 + flowSpecComponent = BgpFsIcmpType.read(tempBuf);
193 + break;
194 + case Constants.BGP_FLOWSPEC_ICMP_CD:
195 + flowSpecComponent = BgpFsIcmpType.read(tempBuf);
196 + break;
197 + case Constants.BGP_FLOWSPEC_TCP_FLAGS:
198 + flowSpecComponent = BgpFsTcpFlags.read(tempBuf);
199 + break;
200 + case Constants.BGP_FLOWSPEC_PCK_LEN:
201 + flowSpecComponent = BgpFsPacketLength.read(tempBuf);
202 + break;
203 + case Constants.BGP_FLOWSPEC_DSCP:
204 + flowSpecComponent = BgpFsDscpValue.read(tempBuf);
205 + break;
206 + case Constants.BGP_FLOWSPEC_FRAGMENT:
207 + flowSpecComponent = BgpFsFragment.read(tempBuf);
208 + break;
209 + default:
210 + log.debug("flow spec type not supported" + type);
211 + break;
212 + }
213 + flowSpecComponents.add(flowSpecComponent);
214 + }
215 + return new MpUnReachNlri(new BgpFlowSpecDetails(flowSpecComponents), afi, safi);
129 } else { 216 } else {
130 //TODO: check with the values got from capability 217 //TODO: check with the values got from capability
131 - throw new BgpParseException("Not Supporting afi " + afi 218 + throw new BgpParseException("Not Supporting afi " + afi + "safi " + safi);
132 - + "safi " + safi);
133 } 219 }
134 } 220 }
135 return new MpUnReachNlri(mpUnReachNlri, afi, safi, 221 return new MpUnReachNlri(mpUnReachNlri, afi, safi,
...@@ -188,8 +274,97 @@ public class MpUnReachNlri implements BgpValueType { ...@@ -188,8 +274,97 @@ public class MpUnReachNlri implements BgpValueType {
188 274
189 @Override 275 @Override
190 public int write(ChannelBuffer cb) { 276 public int write(ChannelBuffer cb) {
191 - //Not to be Implemented as of now 277 + int iLenStartIndex = cb.writerIndex();
192 - return 0; 278 + if ((afi == Constants.AFI_FLOWSPEC_VALUE) && ((safi == Constants.SAFI_FLOWSPEC_VALUE) ||
279 + (safi == Constants.VPN_SAFI_FLOWSPEC_VALUE))) {
280 +
281 + cb.writeByte(FLAGS);
282 + cb.writeByte(MPUNREACHNLRI_TYPE);
283 +
284 + int mpUnReachIndx = cb.writerIndex();
285 + cb.writeShort(0);
286 +
287 + cb.writeShort(afi);
288 + cb.writeByte(safi);
289 +
290 + if (bgpFlowSpecInfo.routeDistinguisher() != null) {
291 + cb.writeLong(bgpFlowSpecInfo.routeDistinguisher().getRouteDistinguisher());
292 + }
293 +
294 + ChannelBuffer flowSpecTmpBuff = ChannelBuffers.dynamicBuffer();
295 + int tmpBuffStartIndx = flowSpecTmpBuff.writerIndex();
296 +
297 + List<BgpValueType> flowSpec = bgpFlowSpecInfo.flowSpecComponents();
298 + ListIterator<BgpValueType> listIterator = flowSpec.listIterator();
299 + while (listIterator.hasNext()) {
300 + BgpValueType tlv = listIterator.next();
301 + switch (tlv.getType()) {
302 + case Constants.BGP_FLOWSPEC_DST_PREFIX:
303 + BgpFsDestinationPrefix fsDstPrefix = (BgpFsDestinationPrefix) tlv;
304 + fsDstPrefix.write(flowSpecTmpBuff);
305 + break;
306 + case Constants.BGP_FLOWSPEC_SRC_PREFIX:
307 + BgpFsSourcePrefix fsSrcPrefix = (BgpFsSourcePrefix) tlv;
308 + fsSrcPrefix.write(flowSpecTmpBuff);
309 + break;
310 + case Constants.BGP_FLOWSPEC_IP_PROTO:
311 + BgpFsIpProtocol fsIpProtocol = (BgpFsIpProtocol) tlv;
312 + fsIpProtocol.write(flowSpecTmpBuff);
313 + break;
314 + case Constants.BGP_FLOWSPEC_PORT:
315 + BgpFsPortNum fsPortNum = (BgpFsPortNum) tlv;
316 + fsPortNum.write(flowSpecTmpBuff);
317 + break;
318 + case Constants.BGP_FLOWSPEC_DST_PORT:
319 + BgpFsDestinationPortNum fsDstPortNum = (BgpFsDestinationPortNum) tlv;
320 + fsDstPortNum.write(flowSpecTmpBuff);
321 + break;
322 + case Constants.BGP_FLOWSPEC_SRC_PORT:
323 + BgpFsSourcePortNum fsSrcPortNum = (BgpFsSourcePortNum) tlv;
324 + fsSrcPortNum.write(flowSpecTmpBuff);
325 + break;
326 + case Constants.BGP_FLOWSPEC_ICMP_TP:
327 + BgpFsIcmpType fsIcmpType = (BgpFsIcmpType) tlv;
328 + fsIcmpType.write(flowSpecTmpBuff);
329 + break;
330 + case Constants.BGP_FLOWSPEC_ICMP_CD:
331 + BgpFsIcmpCode fsIcmpCode = (BgpFsIcmpCode) tlv;
332 + fsIcmpCode.write(flowSpecTmpBuff);
333 + break;
334 + case Constants.BGP_FLOWSPEC_TCP_FLAGS:
335 + BgpFsTcpFlags fsTcpFlags = (BgpFsTcpFlags) tlv;
336 + fsTcpFlags.write(flowSpecTmpBuff);
337 + break;
338 + case Constants.BGP_FLOWSPEC_PCK_LEN:
339 + BgpFsPacketLength fsPacketLen = (BgpFsPacketLength) tlv;
340 + fsPacketLen.write(flowSpecTmpBuff);
341 + break;
342 + case Constants.BGP_FLOWSPEC_DSCP:
343 + BgpFsDscpValue fsDscpVal = (BgpFsDscpValue) tlv;
344 + fsDscpVal.write(flowSpecTmpBuff);
345 + break;
346 + case Constants.BGP_FLOWSPEC_FRAGMENT:
347 + BgpFsFragment fsFragment = (BgpFsFragment) tlv;
348 + fsFragment.write(flowSpecTmpBuff);
349 + break;
350 + default:
351 + }
352 + }
353 +
354 + int len = flowSpecTmpBuff.writerIndex() - tmpBuffStartIndx;
355 + if (len >= FLOW_SPEC_LEN) {
356 + cb.writeShort(len);
357 + } else {
358 + cb.writeByte(len);
359 + }
360 + //Copy from bynamic buffer to channel buffer
361 + cb.writeBytes(flowSpecTmpBuff);
362 +
363 + int fsNlriLen = cb.writerIndex() - mpUnReachIndx;
364 + cb.setShort(mpUnReachIndx, (short) (fsNlriLen - 2));
365 + }
366 +
367 + return cb.writerIndex() - iLenStartIndex;
193 } 368 }
194 369
195 @Override 370 @Override
...@@ -200,8 +375,9 @@ public class MpUnReachNlri implements BgpValueType { ...@@ -200,8 +375,9 @@ public class MpUnReachNlri implements BgpValueType {
200 375
201 @Override 376 @Override
202 public String toString() { 377 public String toString() {
203 - return MoreObjects.toStringHelper(getClass()) 378 + return MoreObjects.toStringHelper(getClass()).omitNullValues()
204 .add("mpReachNlri", mpUnReachNlri) 379 .add("mpReachNlri", mpUnReachNlri)
380 + .add("bgpFlowSpecInfo", bgpFlowSpecInfo)
205 .add("afi", afi) 381 .add("afi", afi)
206 .add("safi", safi) 382 .add("safi", safi)
207 .add("length", length) 383 .add("length", length)
......