[ONOS-4241]Codec for wide community and flow spec
Change-Id: I2dfd6b88c4ae14a02d258a2cdc9ee35b9ff08292
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/MpUnReachNlri.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/MpUnReachNlri.java
index cb871a6..ebeef61 100644
--- a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/MpUnReachNlri.java
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/MpUnReachNlri.java
@@ -21,10 +21,9 @@
import java.util.ListIterator;
import org.jboss.netty.buffer.ChannelBuffer;
-import org.jboss.netty.buffer.ChannelBuffers;
import org.onosproject.bgpio.exceptions.BgpParseException;
import org.onosproject.bgpio.protocol.BgpLSNlri;
-import org.onosproject.bgpio.protocol.flowspec.BgpFlowSpecDetails;
+import org.onosproject.bgpio.protocol.flowspec.BgpFlowSpecNlri;
import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSNlriVer4;
import org.onosproject.bgpio.protocol.linkstate.BgpPrefixIPv4LSNlriVer4;
import org.onosproject.bgpio.protocol.linkstate.BgpLinkLsNlriVer4;
@@ -44,13 +43,12 @@
public static final byte MPUNREACHNLRI_TYPE = 15;
public static final byte LINK_NLRITYPE = 2;
public static final byte FLAGS = (byte) 0x90;
- public static final short FLOW_SPEC_LEN = 240;
private boolean isMpUnReachNlri = false;
private final short afi;
private final byte safi;
private final List<BgpLSNlri> mpUnReachNlri;
private final int length;
- private BgpFlowSpecDetails bgpFlowSpecInfo;
+ private BgpFlowSpecNlri bgpFlowSpecNlri;
/**
* Constructor to initialize parameters.
@@ -69,11 +67,11 @@
this.length = length;
}
- public MpUnReachNlri(BgpFlowSpecDetails bgpFlowSpecInfo, short afi, byte safi) {
+ public MpUnReachNlri(BgpFlowSpecNlri bgpFlowSpecNlri, short afi, byte safi) {
this.mpUnReachNlri = null;
this.isMpUnReachNlri = true;
this.length = 0;
- this.bgpFlowSpecInfo = bgpFlowSpecInfo;
+ this.bgpFlowSpecNlri = bgpFlowSpecNlri;
this.afi = afi;
this.safi = safi;
}
@@ -83,8 +81,8 @@
*
* @return BGP flow specification info
*/
- public BgpFlowSpecDetails bgpFlowSpecInfo() {
- return this.bgpFlowSpecInfo;
+ public BgpFlowSpecNlri bgpFlowSpecNlri() {
+ return this.bgpFlowSpecNlri;
}
/**
@@ -162,64 +160,70 @@
routeDistinguisher = new RouteDistinguisher();
routeDistinguisher = RouteDistinguisher.read(tempCb);
}
- short totNlriLen = tempCb.getByte(tempCb.readerIndex());
- if (totNlriLen >= FLOW_SPEC_LEN) {
- totNlriLen = tempCb.readShort();
- } else {
- totNlriLen = tempCb.readByte();
- }
- if (tempCb.readableBytes() < totNlriLen) {
- Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR,
- BgpErrorType.ATTRIBUTE_LENGTH_ERROR, totNlriLen);
- }
- tempBuf = tempCb.readBytes(totNlriLen);
- while (tempBuf.readableBytes() > 0) {
- short type = tempBuf.readByte();
- switch (type) {
- case Constants.BGP_FLOWSPEC_DST_PREFIX:
- flowSpecComponent = BgpFsDestinationPrefix.read(tempBuf);
- break;
- case Constants.BGP_FLOWSPEC_SRC_PREFIX:
- flowSpecComponent = BgpFsSourcePrefix.read(tempBuf);
- break;
- case Constants.BGP_FLOWSPEC_IP_PROTO:
- flowSpecComponent = BgpFsIpProtocol.read(tempBuf);
- break;
- case Constants.BGP_FLOWSPEC_PORT:
- flowSpecComponent = BgpFsPortNum.read(tempBuf);
- break;
- case Constants.BGP_FLOWSPEC_DST_PORT:
- flowSpecComponent = BgpFsDestinationPortNum.read(tempBuf);
- break;
- case Constants.BGP_FLOWSPEC_SRC_PORT:
- flowSpecComponent = BgpFsSourcePortNum.read(tempBuf);
- break;
- case Constants.BGP_FLOWSPEC_ICMP_TP:
- flowSpecComponent = BgpFsIcmpType.read(tempBuf);
- break;
- case Constants.BGP_FLOWSPEC_ICMP_CD:
- flowSpecComponent = BgpFsIcmpType.read(tempBuf);
- break;
- case Constants.BGP_FLOWSPEC_TCP_FLAGS:
- flowSpecComponent = BgpFsTcpFlags.read(tempBuf);
- break;
- case Constants.BGP_FLOWSPEC_PCK_LEN:
- flowSpecComponent = BgpFsPacketLength.read(tempBuf);
- break;
- case Constants.BGP_FLOWSPEC_DSCP:
- flowSpecComponent = BgpFsDscpValue.read(tempBuf);
- break;
- case Constants.BGP_FLOWSPEC_FRAGMENT:
- flowSpecComponent = BgpFsFragment.read(tempBuf);
- break;
- default:
- log.debug("flow spec type not supported" + type);
- break;
+ while (tempCb.readableBytes() > 0) {
+ short totNlriLen = tempCb.getByte(tempCb.readerIndex());
+ if (totNlriLen >= BgpFlowSpecNlri.FLOW_SPEC_LEN) {
+ if (tempCb.readableBytes() < 2) {
+ Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR,
+ BgpErrorType.ATTRIBUTE_LENGTH_ERROR, totNlriLen);
+ }
+ totNlriLen = tempCb.readShort();
+ } else {
+ totNlriLen = tempCb.readByte();
}
- flowSpecComponents.add(flowSpecComponent);
+ if (tempCb.readableBytes() < totNlriLen) {
+ Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR,
+ BgpErrorType.ATTRIBUTE_LENGTH_ERROR, totNlriLen);
+ }
+ tempBuf = tempCb.readBytes(totNlriLen);
+ while (tempBuf.readableBytes() > 0) {
+ short type = tempBuf.readByte();
+ switch (type) {
+ case Constants.BGP_FLOWSPEC_DST_PREFIX:
+ flowSpecComponent = BgpFsDestinationPrefix.read(tempBuf);
+ break;
+ case Constants.BGP_FLOWSPEC_SRC_PREFIX:
+ flowSpecComponent = BgpFsSourcePrefix.read(tempBuf);
+ break;
+ case Constants.BGP_FLOWSPEC_IP_PROTO:
+ flowSpecComponent = BgpFsIpProtocol.read(tempBuf);
+ break;
+ case Constants.BGP_FLOWSPEC_PORT:
+ flowSpecComponent = BgpFsPortNum.read(tempBuf);
+ break;
+ case Constants.BGP_FLOWSPEC_DST_PORT:
+ flowSpecComponent = BgpFsDestinationPortNum.read(tempBuf);
+ break;
+ case Constants.BGP_FLOWSPEC_SRC_PORT:
+ flowSpecComponent = BgpFsSourcePortNum.read(tempBuf);
+ break;
+ case Constants.BGP_FLOWSPEC_ICMP_TP:
+ flowSpecComponent = BgpFsIcmpType.read(tempBuf);
+ break;
+ case Constants.BGP_FLOWSPEC_ICMP_CD:
+ flowSpecComponent = BgpFsIcmpCode.read(tempBuf);
+ break;
+ case Constants.BGP_FLOWSPEC_TCP_FLAGS:
+ flowSpecComponent = BgpFsTcpFlags.read(tempBuf);
+ break;
+ case Constants.BGP_FLOWSPEC_PCK_LEN:
+ flowSpecComponent = BgpFsPacketLength.read(tempBuf);
+ break;
+ case Constants.BGP_FLOWSPEC_DSCP:
+ flowSpecComponent = BgpFsDscpValue.read(tempBuf);
+ break;
+ case Constants.BGP_FLOWSPEC_FRAGMENT:
+ flowSpecComponent = BgpFsFragment.read(tempBuf);
+ break;
+ default:
+ log.debug("flow spec type not supported" + type);
+ break;
+ }
+ flowSpecComponents.add(flowSpecComponent);
+ }
}
}
- BgpFlowSpecDetails flowSpecDetails = new BgpFlowSpecDetails(flowSpecComponents);
+ BgpFlowSpecNlri flowSpecDetails = new BgpFlowSpecNlri(flowSpecComponents);
flowSpecDetails.setRouteDistinguiher(routeDistinguisher);
return new MpUnReachNlri(flowSpecDetails, afi, safi);
} else {
@@ -286,6 +290,9 @@
int iLenStartIndex = cb.writerIndex();
if ((afi == Constants.AFI_FLOWSPEC_VALUE) && ((safi == Constants.SAFI_FLOWSPEC_VALUE) ||
(safi == Constants.VPN_SAFI_FLOWSPEC_VALUE))) {
+ List<BgpValueType> flowSpec = bgpFlowSpecNlri.flowSpecComponents();
+ ListIterator<BgpValueType> listIterator = flowSpec.listIterator();
+ boolean isAllFlowTypesIdentical = true;
cb.writeByte(FLAGS);
cb.writeByte(MPUNREACHNLRI_TYPE);
@@ -296,79 +303,27 @@
cb.writeShort(afi);
cb.writeByte(safi);
- if (bgpFlowSpecInfo.routeDistinguisher() != null) {
- cb.writeLong(bgpFlowSpecInfo.routeDistinguisher().getRouteDistinguisher());
+ if (bgpFlowSpecNlri.routeDistinguisher() != null) {
+ cb.writeLong(bgpFlowSpecNlri.routeDistinguisher().getRouteDistinguisher());
}
- ChannelBuffer flowSpecTmpBuff = ChannelBuffers.dynamicBuffer();
- int tmpBuffStartIndx = flowSpecTmpBuff.writerIndex();
-
- List<BgpValueType> flowSpec = bgpFlowSpecInfo.flowSpecComponents();
- ListIterator<BgpValueType> listIterator = flowSpec.listIterator();
+ BgpValueType tlv1 = null;
+ if (listIterator.hasNext()) {
+ tlv1 = listIterator.next();
+ }
while (listIterator.hasNext()) {
BgpValueType tlv = listIterator.next();
- switch (tlv.getType()) {
- case Constants.BGP_FLOWSPEC_DST_PREFIX:
- BgpFsDestinationPrefix fsDstPrefix = (BgpFsDestinationPrefix) tlv;
- fsDstPrefix.write(flowSpecTmpBuff);
+ if (tlv.getType() != tlv1.getType()) {
+ isAllFlowTypesIdentical = false;
break;
- case Constants.BGP_FLOWSPEC_SRC_PREFIX:
- BgpFsSourcePrefix fsSrcPrefix = (BgpFsSourcePrefix) tlv;
- fsSrcPrefix.write(flowSpecTmpBuff);
- break;
- case Constants.BGP_FLOWSPEC_IP_PROTO:
- BgpFsIpProtocol fsIpProtocol = (BgpFsIpProtocol) tlv;
- fsIpProtocol.write(flowSpecTmpBuff);
- break;
- case Constants.BGP_FLOWSPEC_PORT:
- BgpFsPortNum fsPortNum = (BgpFsPortNum) tlv;
- fsPortNum.write(flowSpecTmpBuff);
- break;
- case Constants.BGP_FLOWSPEC_DST_PORT:
- BgpFsDestinationPortNum fsDstPortNum = (BgpFsDestinationPortNum) tlv;
- fsDstPortNum.write(flowSpecTmpBuff);
- break;
- case Constants.BGP_FLOWSPEC_SRC_PORT:
- BgpFsSourcePortNum fsSrcPortNum = (BgpFsSourcePortNum) tlv;
- fsSrcPortNum.write(flowSpecTmpBuff);
- break;
- case Constants.BGP_FLOWSPEC_ICMP_TP:
- BgpFsIcmpType fsIcmpType = (BgpFsIcmpType) tlv;
- fsIcmpType.write(flowSpecTmpBuff);
- break;
- case Constants.BGP_FLOWSPEC_ICMP_CD:
- BgpFsIcmpCode fsIcmpCode = (BgpFsIcmpCode) tlv;
- fsIcmpCode.write(flowSpecTmpBuff);
- break;
- case Constants.BGP_FLOWSPEC_TCP_FLAGS:
- BgpFsTcpFlags fsTcpFlags = (BgpFsTcpFlags) tlv;
- fsTcpFlags.write(flowSpecTmpBuff);
- break;
- case Constants.BGP_FLOWSPEC_PCK_LEN:
- BgpFsPacketLength fsPacketLen = (BgpFsPacketLength) tlv;
- fsPacketLen.write(flowSpecTmpBuff);
- break;
- case Constants.BGP_FLOWSPEC_DSCP:
- BgpFsDscpValue fsDscpVal = (BgpFsDscpValue) tlv;
- fsDscpVal.write(flowSpecTmpBuff);
- break;
- case Constants.BGP_FLOWSPEC_FRAGMENT:
- BgpFsFragment fsFragment = (BgpFsFragment) tlv;
- fsFragment.write(flowSpecTmpBuff);
- break;
- default:
}
}
- int len = flowSpecTmpBuff.writerIndex() - tmpBuffStartIndx;
- if (len >= FLOW_SPEC_LEN) {
- cb.writeShort(len);
+ if (isAllFlowTypesIdentical) {
+ BgpFlowSpecNlri.updateBufferIdenticalFlowTypes(cb, bgpFlowSpecNlri());
} else {
- cb.writeByte(len);
+ BgpFlowSpecNlri.updateBufferNonIdenticalFlowTypes(cb, bgpFlowSpecNlri());
}
- //Copy from bynamic buffer to channel buffer
- cb.writeBytes(flowSpecTmpBuff);
-
int fsNlriLen = cb.writerIndex() - mpUnReachIndx;
cb.setShort(mpUnReachIndx, (short) (fsNlriLen - 2));
}
@@ -386,7 +341,7 @@
public String toString() {
return MoreObjects.toStringHelper(getClass()).omitNullValues()
.add("mpReachNlri", mpUnReachNlri)
- .add("bgpFlowSpecInfo", bgpFlowSpecInfo)
+ .add("bgpFlowSpecNlri", bgpFlowSpecNlri)
.add("afi", afi)
.add("safi", safi)
.add("length", length)