Committed by
Gerrit Code Review
[ONOS-3857] BGP flow spec NLRI encoding for MP_REACH and MP_UNREACH.
Change-Id: I44237a12c4235fda2fcfafe60c3935159dae5231
Showing
2 changed files
with
383 additions
and
10 deletions
... | @@ -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) | ... | ... |
-
Please register or login to post a comment