Shashikanth VH

[ONOS-4242] Capability support for wide community

Change-Id: Ib29a4aeddde863d3ecf281cea8d31c6a945834bd
...@@ -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();
......