[ONOS-4242] Capability support for wide community
Change-Id: Ib29a4aeddde863d3ecf281cea8d31c6a945834bd
Showing
11 changed files
with
248 additions
and
25 deletions
... | @@ -331,4 +331,18 @@ public interface BgpCfg { | ... | @@ -331,4 +331,18 @@ public interface BgpCfg { |
331 | * @param flowSpec flow specification capability | 331 | * @param flowSpec flow specification capability |
332 | */ | 332 | */ |
333 | void setFlowSpecCapability(FlowSpec flowSpec); | 333 | void setFlowSpecCapability(FlowSpec flowSpec); |
334 | + | ||
335 | + /** | ||
336 | + * Returns the flow specification route policy distribution capability. | ||
337 | + * | ||
338 | + * @return RDP flow specification capability | ||
339 | + */ | ||
340 | + boolean flowSpecRpdCapability(); | ||
341 | + | ||
342 | + /** | ||
343 | + * Sets the flow specification route policy distribution capability. | ||
344 | + * | ||
345 | + * @param rpdCapability flow specification RPD capability | ||
346 | + */ | ||
347 | + void setFlowSpecRpdCapability(boolean rpdCapability); | ||
334 | } | 348 | } | ... | ... |
... | @@ -139,6 +139,15 @@ public interface BgpOpenMsg extends BgpMessage { | ... | @@ -139,6 +139,15 @@ public interface BgpOpenMsg extends BgpMessage { |
139 | */ | 139 | */ |
140 | Builder setVpnFlowSpecCapabilityTlv(boolean isVpnFlowSpecCapabilitySet); | 140 | Builder setVpnFlowSpecCapabilityTlv(boolean isVpnFlowSpecCapabilitySet); |
141 | 141 | ||
142 | + /** | ||
143 | + * Sets flow specification route distribution policy capability and return its builder. | ||
144 | + * | ||
145 | + * @param isFlowSpecRpdCapabilitySet boolean value to know whether flow spec RPD capability is set or not | ||
146 | + * | ||
147 | + * @return builder by setting capabilities | ||
148 | + */ | ||
149 | + Builder setFlowSpecRpdCapabilityTlv(boolean isFlowSpecRpdCapabilitySet); | ||
150 | + | ||
142 | @Override | 151 | @Override |
143 | Builder setHeader(BgpHeader bgpMsgHeader); | 152 | Builder setHeader(BgpHeader bgpMsgHeader); |
144 | } | 153 | } | ... | ... |
... | @@ -258,16 +258,24 @@ public class BgpOpenMsgVer4 implements BgpOpenMsg { | ... | @@ -258,16 +258,24 @@ public class BgpOpenMsgVer4 implements BgpOpenMsg { |
258 | break; | 258 | break; |
259 | case MultiProtocolExtnCapabilityTlv.TYPE: | 259 | case MultiProtocolExtnCapabilityTlv.TYPE: |
260 | log.debug("MultiProtocolExtnCapabilityTlv"); | 260 | log.debug("MultiProtocolExtnCapabilityTlv"); |
261 | - if (MultiProtocolExtnCapabilityTlv.LENGTH != length) { | 261 | + |
262 | - throw new BgpParseException("Invalid length received for MultiProtocolExtnCapabilityTlv."); | ||
263 | - } | ||
264 | if (length > cb.readableBytes()) { | 262 | if (length > cb.readableBytes()) { |
265 | throw new BgpParseException("BGP LS tlv length is more than readableBytes."); | 263 | throw new BgpParseException("BGP LS tlv length is more than readableBytes."); |
266 | } | 264 | } |
267 | short afi = cb.readShort(); | 265 | short afi = cb.readShort(); |
268 | byte res = cb.readByte(); | 266 | byte res = cb.readByte(); |
269 | byte safi = cb.readByte(); | 267 | byte safi = cb.readByte(); |
270 | - tlv = new MultiProtocolExtnCapabilityTlv(afi, res, safi); | 268 | + if ((afi == Constants.AFI_FLOWSPEC_RPD_VALUE) && (safi == Constants.SAFI_FLOWSPEC_RPD_VALUE)) { |
269 | + if ((MultiProtocolExtnCapabilityTlv.LENGTH + 1) != length) { | ||
270 | + throw new BgpParseException("Invalid length received for MultiProtocolExtnCapabilityTlv."); | ||
271 | + } | ||
272 | + tlv = new MultiProtocolExtnCapabilityTlv(afi, res, safi, cb.readByte()); | ||
273 | + } else { | ||
274 | + if (MultiProtocolExtnCapabilityTlv.LENGTH != length) { | ||
275 | + throw new BgpParseException("Invalid length received for MultiProtocolExtnCapabilityTlv."); | ||
276 | + } | ||
277 | + tlv = new MultiProtocolExtnCapabilityTlv(afi, res, safi); | ||
278 | + } | ||
271 | break; | 279 | break; |
272 | default: | 280 | default: |
273 | log.debug("Warning: Unsupported TLV: " + type); | 281 | log.debug("Warning: Unsupported TLV: " + type); |
... | @@ -297,6 +305,7 @@ public class BgpOpenMsgVer4 implements BgpOpenMsg { | ... | @@ -297,6 +305,7 @@ public class BgpOpenMsgVer4 implements BgpOpenMsg { |
297 | private boolean isLsCapabilityTlvSet = false; | 305 | private boolean isLsCapabilityTlvSet = false; |
298 | private boolean isFlowSpecCapabilityTlvSet = false; | 306 | private boolean isFlowSpecCapabilityTlvSet = false; |
299 | private boolean isVpnFlowSpecCapabilityTlvSet = false; | 307 | private boolean isVpnFlowSpecCapabilityTlvSet = false; |
308 | + private boolean isFlowSpecRpdCapabilityTlvSet = false; | ||
300 | 309 | ||
301 | LinkedList<BgpValueType> capabilityTlv = new LinkedList<>(); | 310 | LinkedList<BgpValueType> capabilityTlv = new LinkedList<>(); |
302 | 311 | ||
... | @@ -347,6 +356,15 @@ public class BgpOpenMsgVer4 implements BgpOpenMsg { | ... | @@ -347,6 +356,15 @@ public class BgpOpenMsgVer4 implements BgpOpenMsg { |
347 | this.capabilityTlv.add(tlv); | 356 | this.capabilityTlv.add(tlv); |
348 | } | 357 | } |
349 | 358 | ||
359 | + if (this.isFlowSpecRpdCapabilityTlvSet) { | ||
360 | + BgpValueType tlv; | ||
361 | + tlv = new MultiProtocolExtnCapabilityTlv(Constants.AFI_FLOWSPEC_RPD_VALUE, | ||
362 | + RES, Constants.SAFI_FLOWSPEC_RPD_VALUE, | ||
363 | + Constants.RPD_CAPABILITY_SEND_VALUE); | ||
364 | + this.capabilityTlv.add(tlv); | ||
365 | + } | ||
366 | + | ||
367 | + | ||
350 | return new BgpOpenMsgVer4(bgpMsgHeader, PACKET_VERSION, this.asNumber, holdTime, this.bgpId, | 368 | return new BgpOpenMsgVer4(bgpMsgHeader, PACKET_VERSION, this.asNumber, holdTime, this.bgpId, |
351 | this.capabilityTlv); | 369 | this.capabilityTlv); |
352 | } | 370 | } |
... | @@ -407,6 +425,12 @@ public class BgpOpenMsgVer4 implements BgpOpenMsg { | ... | @@ -407,6 +425,12 @@ public class BgpOpenMsgVer4 implements BgpOpenMsg { |
407 | this.isVpnFlowSpecCapabilityTlvSet = isVpnFlowSpecCapabilitySet; | 425 | this.isVpnFlowSpecCapabilityTlvSet = isVpnFlowSpecCapabilitySet; |
408 | return this; | 426 | return this; |
409 | } | 427 | } |
428 | + | ||
429 | + @Override | ||
430 | + public Builder setFlowSpecRpdCapabilityTlv(boolean isFlowSpecRpdCapabilityTlvSet) { | ||
431 | + this.isFlowSpecRpdCapabilityTlvSet = isFlowSpecRpdCapabilityTlvSet; | ||
432 | + return this; | ||
433 | + } | ||
410 | } | 434 | } |
411 | 435 | ||
412 | @Override | 436 | @Override | ... | ... |
... | @@ -19,6 +19,7 @@ import com.google.common.base.MoreObjects; | ... | @@ -19,6 +19,7 @@ import com.google.common.base.MoreObjects; |
19 | import org.jboss.netty.buffer.ChannelBuffer; | 19 | import org.jboss.netty.buffer.ChannelBuffer; |
20 | import org.slf4j.Logger; | 20 | import org.slf4j.Logger; |
21 | import org.slf4j.LoggerFactory; | 21 | import org.slf4j.LoggerFactory; |
22 | +import org.onosproject.bgpio.util.Constants; | ||
22 | 23 | ||
23 | import java.util.Objects; | 24 | import java.util.Objects; |
24 | 25 | ||
... | @@ -45,6 +46,7 @@ public class MultiProtocolExtnCapabilityTlv implements BgpValueType { | ... | @@ -45,6 +46,7 @@ public class MultiProtocolExtnCapabilityTlv implements BgpValueType { |
45 | private final short afi; | 46 | private final short afi; |
46 | private final byte res; | 47 | private final byte res; |
47 | private final byte safi; | 48 | private final byte safi; |
49 | + private final byte rpdSendReceive; | ||
48 | 50 | ||
49 | /** | 51 | /** |
50 | * Constructor to initialize variables. | 52 | * Constructor to initialize variables. |
... | @@ -56,6 +58,24 @@ public class MultiProtocolExtnCapabilityTlv implements BgpValueType { | ... | @@ -56,6 +58,24 @@ public class MultiProtocolExtnCapabilityTlv implements BgpValueType { |
56 | this.afi = afi; | 58 | this.afi = afi; |
57 | this.res = res; | 59 | this.res = res; |
58 | this.safi = safi; | 60 | this.safi = safi; |
61 | + this.rpdSendReceive = Constants.RPD_CAPABILITY_SEND_VALUE; | ||
62 | + } | ||
63 | + | ||
64 | + /** | ||
65 | + * Constructor to initialize variables. | ||
66 | + * @param afi Address Family Identifiers | ||
67 | + * @param res reserved field | ||
68 | + * @param safi Subsequent Address Family Identifier | ||
69 | + * @param rpdSendReceive indicates whether the sender is | ||
70 | + (a) willing to receive Route Policies via BGP FLowSpec from its peer (value 1). | ||
71 | + (b) would like to send Route Policies via BGP FLowSpec to its peer (value 2). | ||
72 | + (c) both (value 3). | ||
73 | + */ | ||
74 | + public MultiProtocolExtnCapabilityTlv(short afi, byte res, byte safi, byte rpdSendReceive) { | ||
75 | + this.afi = afi; | ||
76 | + this.res = res; | ||
77 | + this.safi = safi; | ||
78 | + this.rpdSendReceive = rpdSendReceive; | ||
59 | } | 79 | } |
60 | 80 | ||
61 | /** | 81 | /** |
... | @@ -120,9 +140,16 @@ public class MultiProtocolExtnCapabilityTlv implements BgpValueType { | ... | @@ -120,9 +140,16 @@ public class MultiProtocolExtnCapabilityTlv implements BgpValueType { |
120 | 140 | ||
121 | @Override | 141 | @Override |
122 | public int write(ChannelBuffer cb) { | 142 | public int write(ChannelBuffer cb) { |
143 | + boolean isFsRpd = false; | ||
123 | int iLenStartIndex = cb.writerIndex(); | 144 | int iLenStartIndex = cb.writerIndex(); |
124 | cb.writeByte(TYPE); | 145 | cb.writeByte(TYPE); |
125 | - cb.writeByte(LENGTH); | 146 | + |
147 | + if ((afi == Constants.AFI_FLOWSPEC_RPD_VALUE) && (safi == Constants.SAFI_FLOWSPEC_RPD_VALUE)) { | ||
148 | + cb.writeByte(LENGTH + 1); | ||
149 | + isFsRpd = true; | ||
150 | + } else { | ||
151 | + cb.writeByte(LENGTH); | ||
152 | + } | ||
126 | 153 | ||
127 | // write afi | 154 | // write afi |
128 | cb.writeShort(afi); | 155 | cb.writeShort(afi); |
... | @@ -133,6 +160,11 @@ public class MultiProtocolExtnCapabilityTlv implements BgpValueType { | ... | @@ -133,6 +160,11 @@ public class MultiProtocolExtnCapabilityTlv implements BgpValueType { |
133 | // write safi | 160 | // write safi |
134 | cb.writeByte(safi); | 161 | cb.writeByte(safi); |
135 | 162 | ||
163 | + if (isFsRpd) { | ||
164 | + // write Send/Receive (1 octet) | ||
165 | + cb.writeByte(rpdSendReceive); | ||
166 | + } | ||
167 | + | ||
136 | return cb.writerIndex() - iLenStartIndex; | 168 | return cb.writerIndex() - iLenStartIndex; |
137 | } | 169 | } |
138 | 170 | ||
... | @@ -145,6 +177,10 @@ public class MultiProtocolExtnCapabilityTlv implements BgpValueType { | ... | @@ -145,6 +177,10 @@ public class MultiProtocolExtnCapabilityTlv implements BgpValueType { |
145 | short afi = cb.readShort(); | 177 | short afi = cb.readShort(); |
146 | byte res = cb.readByte(); | 178 | byte res = cb.readByte(); |
147 | byte safi = cb.readByte(); | 179 | byte safi = cb.readByte(); |
180 | + | ||
181 | + if ((afi == Constants.AFI_FLOWSPEC_RPD_VALUE) && (safi == Constants.SAFI_FLOWSPEC_RPD_VALUE)) { | ||
182 | + return new MultiProtocolExtnCapabilityTlv(afi, res, safi, cb.readByte()); | ||
183 | + } | ||
148 | return new MultiProtocolExtnCapabilityTlv(afi, res, safi); | 184 | return new MultiProtocolExtnCapabilityTlv(afi, res, safi); |
149 | } | 185 | } |
150 | 186 | ... | ... |
... | @@ -40,6 +40,16 @@ public final class Constants { | ... | @@ -40,6 +40,16 @@ public final class Constants { |
40 | public static final byte SAFI_FLOWSPEC_VALUE = (byte) 133; | 40 | public static final byte SAFI_FLOWSPEC_VALUE = (byte) 133; |
41 | public static final byte VPN_SAFI_FLOWSPEC_VALUE = (byte) 134; | 41 | public static final byte VPN_SAFI_FLOWSPEC_VALUE = (byte) 134; |
42 | 42 | ||
43 | + /* TODO: The Capability Code | ||
44 | + for this capability is to be specified by the IANA.*/ | ||
45 | + public static final short AFI_FLOWSPEC_RPD_VALUE = 1; | ||
46 | + public static final byte SAFI_FLOWSPEC_RPD_VALUE = (byte) 200; | ||
47 | + public static final byte VPN_SAFI_FLOWSPEC_RDP_VALUE = (byte) 201; | ||
48 | + | ||
49 | + public static final byte RPD_CAPABILITY_RECEIVE_VALUE = 0; | ||
50 | + public static final byte RPD_CAPABILITY_SEND_VALUE = 1; | ||
51 | + public static final byte RPD_CAPABILITY_SEND_RECEIVE_VALUE = 2; | ||
52 | + | ||
43 | public static final int EXTRA_TRAFFIC = 0x01; | 53 | public static final int EXTRA_TRAFFIC = 0x01; |
44 | public static final int UNPROTECTED = 0x02; | 54 | public static final int UNPROTECTED = 0x02; |
45 | public static final int SHARED = 0x04; | 55 | public static final int SHARED = 0x04; | ... | ... |
... | @@ -291,15 +291,73 @@ public class BgpOpenMsgTest { | ... | @@ -291,15 +291,73 @@ public class BgpOpenMsgTest { |
291 | public void openMessageTest8() throws BgpParseException { | 291 | public void openMessageTest8() throws BgpParseException { |
292 | 292 | ||
293 | // OPEN Message with invalid message type. | 293 | // OPEN Message with invalid message type. |
294 | - byte[] openMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, | 294 | + byte[] openMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, |
295 | - (byte) 0xff, (byte) 0xff, (byte) 0xff, | 295 | + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, |
296 | - (byte) 0xff, (byte) 0xff, (byte) 0xff, | 296 | + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, 0x00, 0x1d, 0x05, 0X04, |
297 | - (byte) 0xff, (byte) 0xff, (byte) 0xff, | 297 | + (byte) 0xfe, 0x09, 0x00, (byte) 0xb4, (byte) 0xc0, (byte) 0xa8, 0x00, 0x0f, 0x00 }; |
298 | - (byte) 0xff, (byte) 0xff, (byte) 0xff, | 298 | + |
299 | - (byte) 0xff, 0x00, 0x1d, 0x05, 0X04, | 299 | + ChannelBuffer buffer = ChannelBuffers.dynamicBuffer(); |
300 | - (byte) 0xfe, 0x09, 0x00, (byte) 0xb4, | 300 | + buffer.writeBytes(openMsg); |
301 | - (byte) 0xc0, (byte) 0xa8, 0x00, 0x0f, | 301 | + |
302 | - 0x00}; | 302 | + BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader(); |
303 | + BgpMessage message; | ||
304 | + BgpHeader bgpHeader = new BgpHeader(); | ||
305 | + message = reader.readFrom(buffer, bgpHeader); | ||
306 | + | ||
307 | + assertThat(message, instanceOf(BgpOpenMsg.class)); | ||
308 | + } | ||
309 | + | ||
310 | + /** | ||
311 | + * This test case checks open message with route policy distribution capability. | ||
312 | + */ | ||
313 | + @Test | ||
314 | + public void openMessageTest9() throws BgpParseException { | ||
315 | + | ||
316 | + // OPEN Message with capabilities. | ||
317 | + byte[] openMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, | ||
318 | + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, | ||
319 | + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, 0x00, 0x38, 0x01, 0x04, 0x00, | ||
320 | + 0x64, 0x00, (byte) 0xb4, (byte) 0xc0, (byte) 0xa8, 0x07, 0x35, 0x1b, 0x02, 0x19, | ||
321 | + 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, 0x01, 0x04, 0x40, 0x04, 0x00, 0x47, 0x01, | ||
322 | + 0x04, 0x00, 0x01, 0x00, (byte) 0x85, 0x01, 0x05, 0x00, 0x01, 0x00, (byte) 0xc8, | ||
323 | + 0x00 }; // Four Octet AS Number-CAPABILITY-TLV | ||
324 | + | ||
325 | + byte[] testOpenMsg; | ||
326 | + ChannelBuffer buffer = ChannelBuffers.dynamicBuffer(); | ||
327 | + buffer.writeBytes(openMsg); | ||
328 | + | ||
329 | + BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader(); | ||
330 | + BgpMessage message; | ||
331 | + BgpHeader bgpHeader = new BgpHeader(); | ||
332 | + | ||
333 | + message = reader.readFrom(buffer, bgpHeader); | ||
334 | + | ||
335 | + assertThat(message, instanceOf(BgpOpenMsg.class)); | ||
336 | + | ||
337 | + ChannelBuffer buf = ChannelBuffers.dynamicBuffer(); | ||
338 | + message.writeTo(buf); | ||
339 | + | ||
340 | + int readLen = buf.writerIndex(); | ||
341 | + testOpenMsg = new byte[readLen]; | ||
342 | + buf.readBytes(testOpenMsg, 0, readLen); | ||
343 | + | ||
344 | + assertThat(testOpenMsg, is(openMsg)); | ||
345 | + } | ||
346 | + | ||
347 | + /** | ||
348 | + * In this test case, Invalid multiprotocol capability length is given as input and expecting an exception. | ||
349 | + */ | ||
350 | + @Test(expected = BgpParseException.class) | ||
351 | + public void openMessageTest10() throws BgpParseException { | ||
352 | + | ||
353 | + // OPEN Message with invalid message type. | ||
354 | + byte[] openMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, | ||
355 | + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, | ||
356 | + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, 0x00, 0x38, 0x01, 0x04, 0x00, | ||
357 | + 0x64, 0x00, (byte) 0xb4, (byte) 0xc0, (byte) 0xa8, 0x07, 0x35, 0x1b, 0x02, 0x19, | ||
358 | + 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, 0x01, 0x04, 0x40, 0x04, 0x00, 0x47, 0x01, | ||
359 | + 0x04, 0x00, 0x01, 0x00, (byte) 0x85, 0x01, 0x04, 0x00, 0x01, 0x00, (byte) 0xc8, | ||
360 | + 0x00 }; | ||
303 | 361 | ||
304 | ChannelBuffer buffer = ChannelBuffers.dynamicBuffer(); | 362 | ChannelBuffer buffer = ChannelBuffers.dynamicBuffer(); |
305 | buffer.writeBytes(openMsg); | 363 | buffer.writeBytes(openMsg); | ... | ... |
... | @@ -55,9 +55,9 @@ import java.net.SocketAddress; | ... | @@ -55,9 +55,9 @@ import java.net.SocketAddress; |
55 | import java.net.UnknownHostException; | 55 | import java.net.UnknownHostException; |
56 | import java.nio.channels.ClosedChannelException; | 56 | import java.nio.channels.ClosedChannelException; |
57 | import java.util.Collections; | 57 | import java.util.Collections; |
58 | -import java.util.LinkedList; | ||
59 | import java.util.List; | 58 | import java.util.List; |
60 | import java.util.ListIterator; | 59 | import java.util.ListIterator; |
60 | +import java.util.concurrent.CopyOnWriteArrayList; | ||
61 | import java.util.concurrent.RejectedExecutionException; | 61 | import java.util.concurrent.RejectedExecutionException; |
62 | 62 | ||
63 | /** | 63 | /** |
... | @@ -85,6 +85,7 @@ class BgpChannelHandler extends IdleStateAwareChannelHandler { | ... | @@ -85,6 +85,7 @@ class BgpChannelHandler extends IdleStateAwareChannelHandler { |
85 | static final short AFI = 16388; | 85 | static final short AFI = 16388; |
86 | static final byte RES = 0; | 86 | static final byte RES = 0; |
87 | static final byte SAFI = 71; | 87 | static final byte SAFI = 71; |
88 | + static final byte MAX_UNSUPPORTED_CAPABILITY = 5; | ||
88 | 89 | ||
89 | // State needs to be volatile because the HandshakeTimeoutHandler | 90 | // State needs to be volatile because the HandshakeTimeoutHandler |
90 | // needs to check if the handshake is complete | 91 | // needs to check if the handshake is complete |
... | @@ -520,7 +521,7 @@ class BgpChannelHandler extends IdleStateAwareChannelHandler { | ... | @@ -520,7 +521,7 @@ class BgpChannelHandler extends IdleStateAwareChannelHandler { |
520 | byte errorSubCode = errMsg.getErrorSubCode(); | 521 | byte errorSubCode = errMsg.getErrorSubCode(); |
521 | ChannelBuffer tempCb = errMsg.getData(); | 522 | ChannelBuffer tempCb = errMsg.getData(); |
522 | if (tempCb != null) { | 523 | if (tempCb != null) { |
523 | - int dataLength = tempCb.capacity(); | 524 | + int dataLength = tempCb.readableBytes(); |
524 | data = new byte[dataLength]; | 525 | data = new byte[dataLength]; |
525 | tempCb.readBytes(data, 0, dataLength); | 526 | tempCb.readBytes(data, 0, dataLength); |
526 | } | 527 | } |
... | @@ -685,7 +686,8 @@ class BgpChannelHandler extends IdleStateAwareChannelHandler { | ... | @@ -685,7 +686,8 @@ class BgpChannelHandler extends IdleStateAwareChannelHandler { |
685 | .setLsCapabilityTlv(bgpconfig.getLsCapability()) | 686 | .setLsCapabilityTlv(bgpconfig.getLsCapability()) |
686 | .setLargeAsCapabilityTlv(bgpconfig.getLargeASCapability()) | 687 | .setLargeAsCapabilityTlv(bgpconfig.getLargeASCapability()) |
687 | .setFlowSpecCapabilityTlv(flowSpecStatus) | 688 | .setFlowSpecCapabilityTlv(flowSpecStatus) |
688 | - .setVpnFlowSpecCapabilityTlv(vpnFlowSpecStatus).build(); | 689 | + .setVpnFlowSpecCapabilityTlv(vpnFlowSpecStatus) |
690 | + .setFlowSpecRpdCapabilityTlv(bgpconfig.flowSpecRpdCapability()).build(); | ||
689 | log.debug("Sending open message to {}", channel.getRemoteAddress()); | 691 | log.debug("Sending open message to {}", channel.getRemoteAddress()); |
690 | channel.write(Collections.singletonList(msg)); | 692 | channel.write(Collections.singletonList(msg)); |
691 | 693 | ||
... | @@ -786,20 +788,28 @@ class BgpChannelHandler extends IdleStateAwareChannelHandler { | ... | @@ -786,20 +788,28 @@ class BgpChannelHandler extends IdleStateAwareChannelHandler { |
786 | 788 | ||
787 | List<BgpValueType> capabilityTlv = openmsg.getCapabilityTlv(); | 789 | List<BgpValueType> capabilityTlv = openmsg.getCapabilityTlv(); |
788 | ListIterator<BgpValueType> listIterator = capabilityTlv.listIterator(); | 790 | ListIterator<BgpValueType> listIterator = capabilityTlv.listIterator(); |
789 | - List<BgpValueType> unSupportedCapabilityTlv = new LinkedList<>(); | 791 | + List<BgpValueType> unSupportedCapabilityTlv = new CopyOnWriteArrayList<BgpValueType>(); |
790 | ListIterator<BgpValueType> unSupportedCaplistIterator = unSupportedCapabilityTlv.listIterator(); | 792 | ListIterator<BgpValueType> unSupportedCaplistIterator = unSupportedCapabilityTlv.listIterator(); |
791 | BgpValueType tempTlv; | 793 | BgpValueType tempTlv; |
792 | boolean isLargeAsCapabilityCfg = h.bgpconfig.getLargeASCapability(); | 794 | boolean isLargeAsCapabilityCfg = h.bgpconfig.getLargeASCapability(); |
795 | + boolean isFlowSpecRpdCapabilityCfg = h.bgpconfig.flowSpecRpdCapability(); | ||
793 | boolean isLsCapabilityCfg = h.bgpconfig.getLsCapability(); | 796 | boolean isLsCapabilityCfg = h.bgpconfig.getLsCapability(); |
794 | - boolean isFlowSpecCapabilityCfg = false; | 797 | + boolean isFlowSpecIpv4CapabilityCfg = false; |
798 | + boolean isFlowSpecVpnv4CapabilityCfg = false; | ||
795 | MultiProtocolExtnCapabilityTlv tempCapability; | 799 | MultiProtocolExtnCapabilityTlv tempCapability; |
796 | boolean isMultiProtocolLsCapability = false; | 800 | boolean isMultiProtocolLsCapability = false; |
801 | + boolean isMultiProtocolFlowSpecRpdCapability = false; | ||
797 | boolean isMultiProtocolFlowSpecCapability = false; | 802 | boolean isMultiProtocolFlowSpecCapability = false; |
798 | boolean isMultiProtocolVpnFlowSpecCapability = false; | 803 | boolean isMultiProtocolVpnFlowSpecCapability = false; |
799 | BgpCfg.FlowSpec flowSpec = h.bgpconfig.flowSpecCapability(); | 804 | BgpCfg.FlowSpec flowSpec = h.bgpconfig.flowSpecCapability(); |
800 | 805 | ||
801 | - if (flowSpec != BgpCfg.FlowSpec.NONE) { | 806 | + if (flowSpec == BgpCfg.FlowSpec.IPV4) { |
802 | - isFlowSpecCapabilityCfg = true; | 807 | + isFlowSpecIpv4CapabilityCfg = true; |
808 | + } else if (flowSpec == BgpCfg.FlowSpec.VPNV4) { | ||
809 | + isFlowSpecVpnv4CapabilityCfg = true; | ||
810 | + } else if (flowSpec == BgpCfg.FlowSpec.IPV4_VPNV4) { | ||
811 | + isFlowSpecIpv4CapabilityCfg = true; | ||
812 | + isFlowSpecVpnv4CapabilityCfg = true; | ||
803 | } | 813 | } |
804 | 814 | ||
805 | while (listIterator.hasNext()) { | 815 | while (listIterator.hasNext()) { |
... | @@ -817,6 +827,10 @@ class BgpChannelHandler extends IdleStateAwareChannelHandler { | ... | @@ -817,6 +827,10 @@ class BgpChannelHandler extends IdleStateAwareChannelHandler { |
817 | if (SAFI == tempCapability.getSafi()) { | 827 | if (SAFI == tempCapability.getSafi()) { |
818 | isMultiProtocolLsCapability = true; | 828 | isMultiProtocolLsCapability = true; |
819 | } | 829 | } |
830 | + | ||
831 | + if (Constants.SAFI_FLOWSPEC_RPD_VALUE == tempCapability.getSafi()) { | ||
832 | + isMultiProtocolFlowSpecRpdCapability = true; | ||
833 | + } | ||
820 | } | 834 | } |
821 | if (tlv.getType() == FOUR_OCTET_AS_NUM_CAPA_TYPE) { | 835 | if (tlv.getType() == FOUR_OCTET_AS_NUM_CAPA_TYPE) { |
822 | isFourOctetCapabilityExits = true; | 836 | isFourOctetCapabilityExits = true; |
... | @@ -843,13 +857,15 @@ class BgpChannelHandler extends IdleStateAwareChannelHandler { | ... | @@ -843,13 +857,15 @@ class BgpChannelHandler extends IdleStateAwareChannelHandler { |
843 | } | 857 | } |
844 | } | 858 | } |
845 | 859 | ||
846 | - if ((isFlowSpecCapabilityCfg)) { | 860 | + if (isFlowSpecIpv4CapabilityCfg) { |
847 | if (!isMultiProtocolFlowSpecCapability) { | 861 | if (!isMultiProtocolFlowSpecCapability) { |
848 | tempTlv = new MultiProtocolExtnCapabilityTlv(Constants.AFI_FLOWSPEC_VALUE, | 862 | tempTlv = new MultiProtocolExtnCapabilityTlv(Constants.AFI_FLOWSPEC_VALUE, |
849 | RES, Constants.SAFI_FLOWSPEC_VALUE); | 863 | RES, Constants.SAFI_FLOWSPEC_VALUE); |
850 | unSupportedCapabilityTlv.add(tempTlv); | 864 | unSupportedCapabilityTlv.add(tempTlv); |
851 | } | 865 | } |
866 | + } | ||
852 | 867 | ||
868 | + if (isFlowSpecVpnv4CapabilityCfg) { | ||
853 | if (!isMultiProtocolVpnFlowSpecCapability) { | 869 | if (!isMultiProtocolVpnFlowSpecCapability) { |
854 | tempTlv = new MultiProtocolExtnCapabilityTlv(Constants.AFI_FLOWSPEC_VALUE, | 870 | tempTlv = new MultiProtocolExtnCapabilityTlv(Constants.AFI_FLOWSPEC_VALUE, |
855 | RES, Constants.VPN_SAFI_FLOWSPEC_VALUE); | 871 | RES, Constants.VPN_SAFI_FLOWSPEC_VALUE); |
... | @@ -864,7 +880,16 @@ class BgpChannelHandler extends IdleStateAwareChannelHandler { | ... | @@ -864,7 +880,16 @@ class BgpChannelHandler extends IdleStateAwareChannelHandler { |
864 | } | 880 | } |
865 | } | 881 | } |
866 | 882 | ||
867 | - if (unSupportedCapabilityTlv.size() == 3) { | 883 | + if ((isFlowSpecRpdCapabilityCfg)) { |
884 | + if (!isMultiProtocolFlowSpecRpdCapability) { | ||
885 | + tempTlv = new MultiProtocolExtnCapabilityTlv(Constants.AFI_FLOWSPEC_RPD_VALUE, | ||
886 | + RES, Constants.SAFI_FLOWSPEC_RPD_VALUE, | ||
887 | + Constants.RPD_CAPABILITY_SEND_VALUE); | ||
888 | + unSupportedCapabilityTlv.add(tempTlv); | ||
889 | + } | ||
890 | + } | ||
891 | + | ||
892 | + if (unSupportedCapabilityTlv.size() == MAX_UNSUPPORTED_CAPABILITY) { | ||
868 | ChannelBuffer buffer = ChannelBuffers.dynamicBuffer(); | 893 | ChannelBuffer buffer = ChannelBuffers.dynamicBuffer(); |
869 | while (unSupportedCaplistIterator.hasNext()) { | 894 | while (unSupportedCaplistIterator.hasNext()) { |
870 | BgpValueType tlv = unSupportedCaplistIterator.next(); | 895 | BgpValueType tlv = unSupportedCaplistIterator.next(); | ... | ... |
... | @@ -57,6 +57,7 @@ public class BgpConfig implements BgpCfg { | ... | @@ -57,6 +57,7 @@ public class BgpConfig implements BgpCfg { |
57 | private BgpConnectPeer connectPeer; | 57 | private BgpConnectPeer connectPeer; |
58 | private BgpPeerManagerImpl peerManager; | 58 | private BgpPeerManagerImpl peerManager; |
59 | private BgpController bgpController; | 59 | private BgpController bgpController; |
60 | + private boolean rpdCapability; | ||
60 | 61 | ||
61 | /* | 62 | /* |
62 | * Constructor to initialize the values. | 63 | * Constructor to initialize the values. |
... | @@ -129,6 +130,16 @@ public class BgpConfig implements BgpCfg { | ... | @@ -129,6 +130,16 @@ public class BgpConfig implements BgpCfg { |
129 | } | 130 | } |
130 | 131 | ||
131 | @Override | 132 | @Override |
133 | + public boolean flowSpecRpdCapability() { | ||
134 | + return this.rpdCapability; | ||
135 | + } | ||
136 | + | ||
137 | + @Override | ||
138 | + public void setFlowSpecRpdCapability(boolean rpdCapability) { | ||
139 | + this.rpdCapability = rpdCapability; | ||
140 | + } | ||
141 | + | ||
142 | + @Override | ||
132 | public String getRouterId() { | 143 | public String getRouterId() { |
133 | if (this.routerId != null) { | 144 | if (this.routerId != null) { |
134 | return this.routerId.toString(); | 145 | return this.routerId.toString(); | ... | ... |
... | @@ -72,6 +72,7 @@ import org.onosproject.bgpio.types.IsIsNonPseudonode; | ... | @@ -72,6 +72,7 @@ import org.onosproject.bgpio.types.IsIsNonPseudonode; |
72 | import org.onosproject.bgpio.types.MultiProtocolExtnCapabilityTlv; | 72 | import org.onosproject.bgpio.types.MultiProtocolExtnCapabilityTlv; |
73 | import org.onosproject.bgpio.types.IsIsPseudonode; | 73 | import org.onosproject.bgpio.types.IsIsPseudonode; |
74 | import org.onosproject.bgpio.types.RouteDistinguisher; | 74 | import org.onosproject.bgpio.types.RouteDistinguisher; |
75 | +import org.onosproject.bgpio.util.Constants; | ||
75 | 76 | ||
76 | /** | 77 | /** |
77 | * Test case for BGPControllerImpl. | 78 | * Test case for BGPControllerImpl. |
... | @@ -299,6 +300,29 @@ public class BgpControllerImplTest { | ... | @@ -299,6 +300,29 @@ public class BgpControllerImplTest { |
299 | assertThat(result, is(true)); | 300 | assertThat(result, is(true)); |
300 | } | 301 | } |
301 | 302 | ||
303 | + @Test | ||
304 | + public void bgpOpenMessageTest8() throws InterruptedException { | ||
305 | + // Open message with route policy distribution capability | ||
306 | + short afi = Constants.AFI_FLOWSPEC_RPD_VALUE; | ||
307 | + byte res = 0; | ||
308 | + byte safi = Constants.SAFI_FLOWSPEC_RPD_VALUE; | ||
309 | + peer1.peerChannelHandler.asNumber = 200; | ||
310 | + peer1.peerChannelHandler.version = 4; | ||
311 | + peer1.peerChannelHandler.holdTime = 120; | ||
312 | + | ||
313 | + bgpControllerImpl.getConfig().setFlowSpecRpdCapability(true); | ||
314 | + BgpValueType tempTlv1 = new MultiProtocolExtnCapabilityTlv(afi, res, safi); | ||
315 | + peer1.peerChannelHandler.capabilityTlv.add(tempTlv1); | ||
316 | + | ||
317 | + peer1.connect(connectToSocket); | ||
318 | + | ||
319 | + boolean result; | ||
320 | + result = peer1.peerFrameDecoder.receivedOpenMessageLatch.await( | ||
321 | + MESSAGE_TIMEOUT_MS, | ||
322 | + TimeUnit.MILLISECONDS); | ||
323 | + assertThat(result, is(true)); | ||
324 | + } | ||
325 | + | ||
302 | /** | 326 | /** |
303 | * Peer1 has Node NLRI (MpReach). | 327 | * Peer1 has Node NLRI (MpReach). |
304 | */ | 328 | */ | ... | ... |
... | @@ -48,6 +48,7 @@ public class BgpAppConfig extends Config<ApplicationId> { | ... | @@ -48,6 +48,7 @@ public class BgpAppConfig extends Config<ApplicationId> { |
48 | public static final String HOLD_TIME = "holdTime"; | 48 | public static final String HOLD_TIME = "holdTime"; |
49 | public static final String LARGE_AS_CAPABILITY = "largeAsCapability"; | 49 | public static final String LARGE_AS_CAPABILITY = "largeAsCapability"; |
50 | public static final String FLOW_SPEC_CAPABILITY = "flowSpecCapability"; | 50 | public static final String FLOW_SPEC_CAPABILITY = "flowSpecCapability"; |
51 | + public static final String FLOW_SPEC_RPD_CAPABILITY = "flowSpecRpdCapability"; | ||
51 | 52 | ||
52 | public static final String BGP_PEER = "bgpPeer"; | 53 | public static final String BGP_PEER = "bgpPeer"; |
53 | public static final String PEER_IP = "peerIp"; | 54 | public static final String PEER_IP = "peerIp"; |
... | @@ -68,11 +69,11 @@ public class BgpAppConfig extends Config<ApplicationId> { | ... | @@ -68,11 +69,11 @@ public class BgpAppConfig extends Config<ApplicationId> { |
68 | bgpConfig = bgpController.getConfig(); | 69 | bgpConfig = bgpController.getConfig(); |
69 | 70 | ||
70 | fields = hasOnlyFields(ROUTER_ID, LOCAL_AS, MAX_SESSION, LS_CAPABILITY, | 71 | fields = hasOnlyFields(ROUTER_ID, LOCAL_AS, MAX_SESSION, LS_CAPABILITY, |
71 | - HOLD_TIME, LARGE_AS_CAPABILITY, FLOW_SPEC_CAPABILITY, BGP_PEER) && | 72 | + HOLD_TIME, LARGE_AS_CAPABILITY, FLOW_SPEC_CAPABILITY, FLOW_SPEC_RPD_CAPABILITY, BGP_PEER) && |
72 | isIpAddress(ROUTER_ID, MANDATORY) && isNumber(LOCAL_AS, MANDATORY) && | 73 | isIpAddress(ROUTER_ID, MANDATORY) && isNumber(LOCAL_AS, MANDATORY) && |
73 | isNumber(MAX_SESSION, OPTIONAL, 20) && isNumber(HOLD_TIME, OPTIONAL, 180) && | 74 | isNumber(MAX_SESSION, OPTIONAL, 20) && isNumber(HOLD_TIME, OPTIONAL, 180) && |
74 | isBoolean(LS_CAPABILITY, OPTIONAL) && isBoolean(LARGE_AS_CAPABILITY, OPTIONAL) && | 75 | isBoolean(LS_CAPABILITY, OPTIONAL) && isBoolean(LARGE_AS_CAPABILITY, OPTIONAL) && |
75 | - isString(FLOW_SPEC_CAPABILITY, OPTIONAL); | 76 | + isString(FLOW_SPEC_CAPABILITY, OPTIONAL) && isBoolean(FLOW_SPEC_RPD_CAPABILITY, OPTIONAL); |
76 | 77 | ||
77 | if (!fields) { | 78 | if (!fields) { |
78 | return fields; | 79 | return fields; |
... | @@ -118,6 +119,15 @@ public class BgpAppConfig extends Config<ApplicationId> { | ... | @@ -118,6 +119,15 @@ public class BgpAppConfig extends Config<ApplicationId> { |
118 | } | 119 | } |
119 | 120 | ||
120 | /** | 121 | /** |
122 | + * Returns flow spec route policy distribution capability support from the configuration. | ||
123 | + * | ||
124 | + * @return true if flow spec route policy distribution capability is set otherwise false | ||
125 | + */ | ||
126 | + public boolean rpdCapability() { | ||
127 | + return Boolean.parseBoolean(get(FLOW_SPEC_RPD_CAPABILITY, null)); | ||
128 | + } | ||
129 | + | ||
130 | + /** | ||
121 | * Returns largeAs capability support from the configuration. | 131 | * Returns largeAs capability support from the configuration. |
122 | * | 132 | * |
123 | * @return largeAs capability | 133 | * @return largeAs capability | ... | ... |
... | @@ -137,6 +137,7 @@ public class BgpCfgProvider extends AbstractProvider { | ... | @@ -137,6 +137,7 @@ public class BgpCfgProvider extends AbstractProvider { |
137 | } else { | 137 | } else { |
138 | bgpConfig.setFlowSpecCapability(BgpCfg.FlowSpec.NONE); | 138 | bgpConfig.setFlowSpecCapability(BgpCfg.FlowSpec.NONE); |
139 | } | 139 | } |
140 | + bgpConfig.setFlowSpecRpdCapability(config.rpdCapability()); | ||
140 | 141 | ||
141 | nodes = config.bgpPeer(); | 142 | nodes = config.bgpPeer(); |
142 | for (int i = 0; i < nodes.size(); i++) { | 143 | for (int i = 0; i < nodes.size(); i++) { |
... | @@ -186,6 +187,7 @@ public class BgpCfgProvider extends AbstractProvider { | ... | @@ -186,6 +187,7 @@ public class BgpCfgProvider extends AbstractProvider { |
186 | } else { | 187 | } else { |
187 | log.info(" Self configuration cannot be modified as there is existing connections "); | 188 | log.info(" Self configuration cannot be modified as there is existing connections "); |
188 | } | 189 | } |
190 | + bgpConfig.setFlowSpecRpdCapability(config.rpdCapability()); | ||
189 | 191 | ||
190 | /* update the peer configuration */ | 192 | /* update the peer configuration */ |
191 | bgpPeerTree = bgpConfig.getPeerTree(); | 193 | bgpPeerTree = bgpConfig.getPeerTree(); | ... | ... |
-
Please register or login to post a comment