[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