Shashikanth VH
Committed by Gerrit Code Review

[ONOS-3856] BGP flow specification update message encode.

Change-Id: I4286ea636df154f64c5b27f1f55a26fdc257e4f3
......@@ -21,7 +21,6 @@ import java.util.List;
import org.jboss.netty.buffer.ChannelBuffer;
import org.onlab.packet.IpPrefix;
import org.onosproject.bgpio.protocol.ver4.BgpPathAttributes;
import org.onosproject.bgpio.protocol.flowspec.BgpFlowSpecDetails;
import org.onosproject.bgpio.types.BgpValueType;
import org.onosproject.bgpio.types.BgpHeader;
......@@ -51,10 +50,6 @@ public interface BgpUpdateMsg extends BgpMessage {
Builder setBgpPathAttributes(List<BgpValueType> attributes);
Builder setNlriIdentifier(short afi, byte safi);
Builder setBgpFlowSpecComponents(BgpFlowSpecDetails flowSpecComponents);
@Override
Builder setHeader(BgpHeader bgpMsgHeader);
}
......
......@@ -27,8 +27,8 @@ import com.google.common.base.MoreObjects;
*/
public class BgpFlowSpecDetails {
private List<BgpValueType> flowSpecComponents;
BgpValueType fsActionTlv;
RouteDistinguisher routeDistinguisher;
private BgpValueType fsActionTlv;
private RouteDistinguisher routeDistinguisher;
/**
* Flow specification details object constructor with the parameter.
......
......@@ -17,12 +17,14 @@ package org.onosproject.bgpio.protocol.ver4;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import org.jboss.netty.buffer.ChannelBuffer;
import org.onosproject.bgpio.exceptions.BgpParseException;
import org.onosproject.bgpio.types.As4Path;
import org.onosproject.bgpio.types.AsPath;
import org.onosproject.bgpio.types.BgpErrorType;
import org.onosproject.bgpio.types.BgpExtendedCommunity;
import org.onosproject.bgpio.types.BgpValueType;
import org.onosproject.bgpio.types.LinkStateAttributes;
import org.onosproject.bgpio.types.LocalPref;
......@@ -33,6 +35,7 @@ import org.onosproject.bgpio.types.MpReachNlri;
import org.onosproject.bgpio.types.MpUnReachNlri;
import org.onosproject.bgpio.util.UnSupportedAttribute;
import org.onosproject.bgpio.util.Validation;
import org.onosproject.bgpio.util.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -58,6 +61,7 @@ public class BgpPathAttributes {
public static final int LINK_STATE_ATTRIBUTE_TYPE = 29;
public static final int MPREACHNLRI_TYPE = 14;
public static final int MPUNREACHNLRI_TYPE = 15;
public static final int EXTENDED_COMMUNITY_TYPE = 16;
private final List<BgpValueType> pathAttribute;
......@@ -142,6 +146,9 @@ public class BgpPathAttributes {
case LINK_STATE_ATTRIBUTE_TYPE:
pathAttribute = LinkStateAttributes.read(cb);
break;
case EXTENDED_COMMUNITY_TYPE:
pathAttribute = BgpExtendedCommunity.read(cb);
break;
default:
//skip bytes for unsupported attribute types
UnSupportedAttribute.read(cb);
......@@ -155,6 +162,81 @@ public class BgpPathAttributes {
}
/**
* Write path attributes to channelBuffer.
*
* @param cb channelBuffer
* @return object of BgpPathAttributes
* @throws BgpParseException while parsing BGP path attributes
*/
public int write(ChannelBuffer cb)
throws BgpParseException {
if (pathAttribute == null) {
return 0;
}
int iLenStartIndex = cb.writerIndex();
ListIterator<BgpValueType> iterator = pathAttribute.listIterator();
int pathAttributeIndx = cb.writerIndex();
cb.writeShort(0);
while (iterator.hasNext()) {
BgpValueType attr = iterator.next();
switch (attr.getType()) {
case Origin.ORIGIN_TYPE:
Origin origin = (Origin) attr;
origin.write(cb);
break;
case AsPath.ASPATH_TYPE:
AsPath asPath = (AsPath) attr;
asPath.write(cb);
break;
case As4Path.AS4PATH_TYPE:
As4Path as4Path = (As4Path) attr;
as4Path.write(cb);
break;
case NextHop.NEXTHOP_TYPE:
NextHop nextHop = (NextHop) attr;
nextHop.write(cb);
break;
case Med.MED_TYPE:
Med med = (Med) attr;
med.write(cb);
break;
case LocalPref.LOCAL_PREF_TYPE:
LocalPref localPref = (LocalPref) attr;
localPref.write(cb);
break;
case Constants.BGP_EXTENDED_COMMUNITY:
BgpExtendedCommunity extendedCommunity = (BgpExtendedCommunity) attr;
extendedCommunity.write(cb);
break;
case MpReachNlri.MPREACHNLRI_TYPE:
MpReachNlri mpReach = (MpReachNlri) attr;
mpReach.write(cb);
break;
case MpUnReachNlri.MPUNREACHNLRI_TYPE:
MpUnReachNlri mpUnReach = (MpUnReachNlri) attr;
mpUnReach.write(cb);
break;
case LINK_STATE_ATTRIBUTE_TYPE:
LinkStateAttributes linkState = (LinkStateAttributes) attr;
linkState.write(cb);
break;
default:
return cb.writerIndex() - iLenStartIndex;
}
}
int pathAttrLen = cb.writerIndex() - pathAttributeIndx;
cb.setShort(pathAttributeIndx, (short) (pathAttrLen - 2));
return cb.writerIndex() - iLenStartIndex;
}
/**
* Checks mandatory attributes are presents, if not present throws exception.
*
* @param isOrigin say whether origin attribute is present
......
......@@ -15,6 +15,7 @@
*/
package org.onosproject.bgpio.protocol.ver4;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
......@@ -26,9 +27,10 @@ import org.onosproject.bgpio.protocol.BgpMessageWriter;
import org.onosproject.bgpio.protocol.BgpType;
import org.onosproject.bgpio.protocol.BgpUpdateMsg;
import org.onosproject.bgpio.protocol.BgpVersion;
import org.onosproject.bgpio.protocol.flowspec.BgpFlowSpecDetails;
import org.onosproject.bgpio.types.BgpErrorType;
import org.onosproject.bgpio.types.BgpHeader;
import org.onosproject.bgpio.types.MpReachNlri;
import org.onosproject.bgpio.types.MpUnReachNlri;
import org.onosproject.bgpio.util.Constants;
import org.onosproject.bgpio.util.Validation;
......@@ -94,9 +96,6 @@ public class BgpUpdateMsgVer4 implements BgpUpdateMsg {
private BgpPathAttributes bgpPathAttributes;
private BgpHeader bgpHeader;
private List<IpPrefix> nlri;
private BgpFlowSpecDetails bgpFlowSpecComponents;
private short afi;
private byte safi;
/**
* Constructor to initialize parameters for BGP Update message.
......@@ -114,15 +113,6 @@ public class BgpUpdateMsgVer4 implements BgpUpdateMsg {
this.nlri = nlri;
}
public BgpUpdateMsgVer4(BgpHeader bgpHeader, short afi, byte safi, BgpPathAttributes bgpPathAttributes,
BgpFlowSpecDetails bgpFlowSpecComponents) {
this.bgpHeader = bgpHeader;
this.bgpFlowSpecComponents = bgpFlowSpecComponents;
this.bgpPathAttributes = bgpPathAttributes;
this.afi = afi;
this.safi = safi;
}
/**
* Reader reads BGP Update Message from the channel buffer.
*/
......@@ -191,16 +181,15 @@ public class BgpUpdateMsgVer4 implements BgpUpdateMsg {
*/
static class Builder implements BgpUpdateMsg.Builder {
BgpHeader bgpMsgHeader = null;
BgpFlowSpecDetails bgpFlowSpecComponents;
BgpPathAttributes bgpPathAttributes;
private short afi;
private byte safi;
List<IpPrefix> withdrawnRoutes;
List<IpPrefix> nlri;
@Override
public BgpUpdateMsg build() /* throws BgpParseException */ {
public BgpUpdateMsg build() {
BgpHeader bgpMsgHeader = DEFAULT_UPDATE_HEADER;
return new BgpUpdateMsgVer4(bgpMsgHeader, afi, safi, bgpPathAttributes, bgpFlowSpecComponents);
return new BgpUpdateMsgVer4(bgpMsgHeader, withdrawnRoutes, bgpPathAttributes, nlri);
}
@Override
......@@ -210,23 +199,11 @@ public class BgpUpdateMsgVer4 implements BgpUpdateMsg {
}
@Override
public Builder setBgpFlowSpecComponents(BgpFlowSpecDetails bgpFlowSpecComponents) {
this.bgpFlowSpecComponents = bgpFlowSpecComponents;
return this;
}
@Override
public Builder setBgpPathAttributes(List<BgpValueType> attributes) {
this.bgpPathAttributes = new BgpPathAttributes(attributes);
return this;
}
@Override
public Builder setNlriIdentifier(short afi, byte safi) {
this.afi = afi;
this.safi = safi;
return this;
}
}
public static final Writer WRITER = new Writer();
......@@ -240,6 +217,8 @@ public class BgpUpdateMsgVer4 implements BgpUpdateMsg {
public void write(ChannelBuffer cb, BgpUpdateMsgVer4 message) throws BgpParseException {
int startIndex = cb.writerIndex();
short afi = 0;
byte safi = 0;
// write common header and get msg length index
int msgLenIndex = message.bgpHeader.write(cb);
......@@ -247,13 +226,34 @@ public class BgpUpdateMsgVer4 implements BgpUpdateMsg {
if (msgLenIndex <= 0) {
throw new BgpParseException("Unable to write message header.");
}
List<BgpValueType> pathAttr = message.bgpPathAttributes.pathAttributes();
if (pathAttr != null) {
Iterator<BgpValueType> listIterator = pathAttr.iterator();
while (listIterator.hasNext()) {
BgpValueType attr = listIterator.next();
if (attr instanceof MpReachNlri) {
MpReachNlri mpReach = (MpReachNlri) attr;
afi = mpReach.afi();
safi = mpReach.safi();
} else if (attr instanceof MpUnReachNlri) {
MpUnReachNlri mpUnReach = (MpUnReachNlri) attr;
afi = mpUnReach.afi();
safi = mpUnReach.safi();
}
if ((afi == Constants.AFI_FLOWSPEC_VALUE) && ((safi == Constants.SAFI_FLOWSPEC_VALUE)
|| (safi == Constants.VPN_SAFI_FLOWSPEC_VALUE))) {
//unfeasible route length
cb.writeShort(0);
}
}
if ((message.afi == Constants.AFI_FLOWSPEC_VALUE) && (message.safi == Constants.SAFI_FLOWSPEC_VALUE)) {
//unfeasible route length
cb.writeShort(0);
}
// TODO: write path attributes
if (message.bgpPathAttributes != null) {
message.bgpPathAttributes.write(cb);
}
// write UPDATE Object Length
int length = cb.writerIndex() - startIndex;
......