Shashikanth VH
Committed by ShashikanthVH-Huawei

BGP flow spec RIBin.

Change-Id: I4909bb6e579311a74e25cb44172a2a010faa4e85
......@@ -124,6 +124,14 @@ public interface BgpPeer {
void buildAdjRibIn(List<BgpValueType> pathAttr) throws BgpParseException;
/**
* Update flow specification RIB for each peer.
*
* @param pathAttr list of Bgp path attributes
* @throws BgpParseException while building flow spec RIB
*/
void buildFlowSpecRib(List<BgpValueType> pathAttr) throws BgpParseException;
/**
* Return the BGP session info.
*
* @return sessionInfo bgp session info
......
......@@ -40,6 +40,14 @@ public class BgpFlowSpecDetails {
}
/**
* Flow specification details object constructor.
*
*/
public BgpFlowSpecDetails() {
}
/**
* Returns flow specification action tlv.
*
* @return flow specification action tlv
......@@ -84,6 +92,15 @@ public class BgpFlowSpecDetails {
return this.flowSpecComponents;
}
/**
* Sets flow specification components.
*
* @param flowSpecComponents flow specification components
*/
public void setFlowSpecComponents(List<BgpValueType> flowSpecComponents) {
this.flowSpecComponents = flowSpecComponents;
}
@Override
public int hashCode() {
return Objects.hash(flowSpecComponents);
......
......@@ -41,6 +41,14 @@ public class BgpFlowSpecPrefix implements Comparable<Object> {
* @param sourcePrefix source prefix
*/
public BgpFlowSpecPrefix(IpPrefix destinationPrefix, IpPrefix sourcePrefix) {
if (destinationPrefix == null) {
destinationPrefix = IpPrefix.valueOf(0, 0);
}
if (sourcePrefix == null) {
sourcePrefix = IpPrefix.valueOf(0, 0);
}
this.destinationPrefix = destinationPrefix;
this.sourcePrefix = sourcePrefix;
}
......
......@@ -189,7 +189,7 @@ public class MpReachNlri implements BgpValueType {
&& ((safi == Constants.SAFI_FLOWSPEC_VALUE)
|| (safi == Constants.VPN_SAFI_FLOWSPEC_VALUE))) {
List<BgpValueType> flowSpecComponents = new LinkedList<>();
RouteDistinguisher routeDistinguisher = null;
if (tempCb.readableBytes() > 0) {
BgpValueType flowSpecComponent = null;
......@@ -203,6 +203,11 @@ public class MpReachNlri implements BgpValueType {
}
byte reserved = tempCb.readByte();
if (safi == Constants.VPN_SAFI_FLOWSPEC_VALUE) {
routeDistinguisher = new RouteDistinguisher();
routeDistinguisher = RouteDistinguisher.read(tempCb);
}
short totNlriLen = tempCb.getByte(tempCb.readerIndex());
if (totNlriLen >= FLOW_SPEC_LEN) {
totNlriLen = tempCb.readShort();
......@@ -260,7 +265,9 @@ public class MpReachNlri implements BgpValueType {
flowSpecComponents.add(flowSpecComponent);
}
}
return new MpReachNlri(new BgpFlowSpecDetails(flowSpecComponents), afi, safi);
BgpFlowSpecDetails flowSpecDetails = new BgpFlowSpecDetails(flowSpecComponents);
flowSpecDetails.setRouteDistinguiher(routeDistinguisher);
return new MpReachNlri(flowSpecDetails, afi, safi);
} else {
throw new BgpParseException("Not Supporting afi " + afi + "safi " + safi);
}
......
......@@ -154,9 +154,14 @@ public class MpUnReachNlri implements BgpValueType {
&& ((safi == Constants.SAFI_FLOWSPEC_VALUE)
|| (safi == Constants.VPN_SAFI_FLOWSPEC_VALUE))) {
List<BgpValueType> flowSpecComponents = new LinkedList<>();
RouteDistinguisher routeDistinguisher = null;
if (tempCb.readableBytes() > 0) {
BgpValueType flowSpecComponent = null;
if (safi == Constants.VPN_SAFI_FLOWSPEC_VALUE) {
routeDistinguisher = new RouteDistinguisher();
routeDistinguisher = RouteDistinguisher.read(tempCb);
}
short totNlriLen = tempCb.getByte(tempCb.readerIndex());
if (totNlriLen >= FLOW_SPEC_LEN) {
totNlriLen = tempCb.readShort();
......@@ -214,7 +219,9 @@ public class MpUnReachNlri implements BgpValueType {
flowSpecComponents.add(flowSpecComponent);
}
}
return new MpUnReachNlri(new BgpFlowSpecDetails(flowSpecComponents), afi, safi);
BgpFlowSpecDetails flowSpecDetails = new BgpFlowSpecDetails(flowSpecComponents);
flowSpecDetails.setRouteDistinguiher(routeDistinguisher);
return new MpUnReachNlri(flowSpecDetails, afi, safi);
} else {
//TODO: check with the values got from capability
throw new BgpParseException("Not Supporting afi " + afi + "safi " + safi);
......
......@@ -131,22 +131,29 @@ public class BgpControllerImpl implements BgpController {
}
Iterator<BgpValueType> listIterator = pathAttr.iterator();
boolean isLinkstate = false;
boolean isFlowSpec = false;
while (listIterator.hasNext()) {
BgpValueType attr = listIterator.next();
if (attr instanceof MpReachNlri) {
MpReachNlri mpReach = (MpReachNlri) attr;
if (mpReach.bgpFlowSpecInfo() == null) {
isLinkstate = true;
} else {
isFlowSpec = true;
}
} else if (attr instanceof MpUnReachNlri) {
MpUnReachNlri mpUnReach = (MpUnReachNlri) attr;
if (mpUnReach.bgpFlowSpecInfo() == null) {
isLinkstate = true;
} else {
isFlowSpec = true;
}
}
}
if (isLinkstate) {
peer.buildAdjRibIn(pathAttr);
} else if (isFlowSpec) {
peer.buildFlowSpecRib(pathAttr);
}
break;
default:
......
......@@ -26,9 +26,9 @@ import org.onosproject.bgpio.protocol.flowspec.BgpFlowSpecPrefix;
import com.google.common.base.MoreObjects;
/**
* Implementation of BGP flow spec RIB out for each peer.
* Implementation of BGP flow specification RIB.
*/
public class BgpFlowSpecRibOut {
public class BgpFlowSpecRib {
private Map<BgpFlowSpecPrefix, BgpFlowSpecDetails> flowSpecTree = new TreeMap<>();
private Map<RouteDistinguisher, Map<BgpFlowSpecPrefix, BgpFlowSpecDetails>> vpnFlowSpecTree = new TreeMap<>();
......
......@@ -26,6 +26,7 @@ import java.util.Set;
import org.jboss.netty.channel.Channel;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onosproject.bgp.controller.BgpController;
import org.onosproject.bgp.controller.BgpLocalRib;
import org.onosproject.bgp.controller.BgpPeer;
......@@ -44,6 +45,8 @@ import org.onosproject.bgpio.protocol.linkstate.PathAttrNlriDetails;
import org.onosproject.bgpio.types.AsPath;
import org.onosproject.bgpio.types.As4Path;
import org.onosproject.bgpio.types.BgpExtendedCommunity;
import org.onosproject.bgpio.types.BgpFsDestinationPrefix;
import org.onosproject.bgpio.types.BgpFsSourcePrefix;
import org.onosproject.bgpio.types.BgpValueType;
import org.onosproject.bgpio.types.LocalPref;
import org.onosproject.bgpio.types.Med;
......@@ -83,25 +86,25 @@ public class BgpPeerImpl implements BgpPeer {
private BgpLocalRib bgplocalRibVpn;
private AdjRibIn adjRib;
private VpnAdjRibIn vpnAdjRib;
private BgpFlowSpecRibOut flowSpecRibOut;
private BgpFlowSpecRibOut vpnFlowSpecRibOut;
private BgpFlowSpecRib flowSpecRibOut;
private BgpFlowSpecRib flowSpecRibIn;
/**
* Returns the flowSpec RIB out.
*
* @return flow Specification RIB out
*/
public BgpFlowSpecRibOut flowSpecRibOut() {
public BgpFlowSpecRib flowSpecRibOut() {
return flowSpecRibOut;
}
/**
* Returns the VPN flowSpec RIB out.
* Returns the flowSpec RIB-in.
*
* @return VPN flow Specification RIB out
* @return flow Specification RIB-in
*/
public BgpFlowSpecRibOut vpnFlowSpecRibOut() {
return vpnFlowSpecRibOut;
public BgpFlowSpecRib flowSpecRibIn() {
return flowSpecRibIn;
}
/**
......@@ -142,8 +145,8 @@ public class BgpPeerImpl implements BgpPeer {
this.bgplocalRibVpn = bgpController.bgpLocalRibVpn();
this.adjRib = new AdjRibIn();
this.vpnAdjRib = new VpnAdjRibIn();
this.flowSpecRibOut = new BgpFlowSpecRibOut();
this.vpnFlowSpecRibOut = new BgpFlowSpecRibOut();
this.flowSpecRibOut = new BgpFlowSpecRib();
this.flowSpecRibIn = new BgpFlowSpecRib();
}
/**
......@@ -258,21 +261,21 @@ public class BgpPeerImpl implements BgpPeer {
}
flowSpecRibOut.add(prefix, flowSpec);
} else {
if (vpnFlowSpecRibOut.vpnFlowSpecTree().containsKey(flowSpec.routeDistinguisher())) {
if (flowSpecRibOut.vpnFlowSpecTree().containsKey(flowSpec.routeDistinguisher())) {
Map<BgpFlowSpecPrefix, BgpFlowSpecDetails> fsTree;
fsTree = vpnFlowSpecRibOut.vpnFlowSpecTree().get(flowSpec.routeDistinguisher());
fsTree = flowSpecRibOut.vpnFlowSpecTree().get(flowSpec.routeDistinguisher());
if (fsTree.containsKey(prefix)) {
sendFlowSpecUpdateMessageToPeer(FlowSpecOperation.DELETE,
fsTree.get(prefix));
}
}
vpnFlowSpecRibOut.add(flowSpec.routeDistinguisher(), prefix, flowSpec);
flowSpecRibOut.add(flowSpec.routeDistinguisher(), prefix, flowSpec);
}
} else if (operType == FlowSpecOperation.DELETE) {
if (flowSpec.routeDistinguisher() == null) {
flowSpecRibOut.delete(prefix);
} else {
vpnFlowSpecRibOut.delete(flowSpec.routeDistinguisher(), prefix);
flowSpecRibOut.delete(flowSpec.routeDistinguisher(), prefix);
}
}
sendFlowSpecUpdateMessageToPeer(operType, flowSpec);
......@@ -294,6 +297,65 @@ public class BgpPeerImpl implements BgpPeer {
}
}
@Override
public void buildFlowSpecRib(List<BgpValueType> pathAttr) throws BgpParseException {
ListIterator<BgpValueType> iterator = pathAttr.listIterator();
BgpFlowSpecDetails bgpFlowSpecDetails = new BgpFlowSpecDetails();
FlowSpecOperation operType = FlowSpecOperation.UPDATE;
while (iterator.hasNext()) {
BgpValueType attr = iterator.next();
if (attr instanceof MpReachNlri) {
MpReachNlri mpReach = (MpReachNlri) attr;
bgpFlowSpecDetails.setFlowSpecComponents(mpReach.bgpFlowSpecInfo().flowSpecComponents());
bgpFlowSpecDetails.setRouteDistinguiher(mpReach.bgpFlowSpecInfo().routeDistinguisher());
operType = FlowSpecOperation.ADD;
}
if (attr instanceof BgpExtendedCommunity) {
BgpExtendedCommunity extCommunity = (BgpExtendedCommunity) attr;
bgpFlowSpecDetails.setFsActionTlv(extCommunity.fsActionTlv());
}
if (attr instanceof MpUnReachNlri) {
MpUnReachNlri mpUnReach = (MpUnReachNlri) attr;
bgpFlowSpecDetails.setFlowSpecComponents(mpUnReach.bgpFlowSpecInfo().flowSpecComponents());
bgpFlowSpecDetails.setRouteDistinguiher(mpUnReach.bgpFlowSpecInfo().routeDistinguisher());
operType = FlowSpecOperation.DELETE;
}
}
iterator = bgpFlowSpecDetails.flowSpecComponents().listIterator();
IpPrefix destIpPrefix = null;
IpPrefix srcIpPrefix = null;
while (iterator.hasNext()) {
BgpValueType fsAttr = iterator.next();
if (fsAttr instanceof BgpFsDestinationPrefix) {
BgpFsDestinationPrefix destinationPrefix = (BgpFsDestinationPrefix) fsAttr;
destIpPrefix = destinationPrefix.ipPrefix();
}
if (fsAttr instanceof BgpFsSourcePrefix) {
BgpFsSourcePrefix sourcePrefix = (BgpFsSourcePrefix) fsAttr;
srcIpPrefix = sourcePrefix.ipPrefix();
}
}
BgpFlowSpecPrefix prefix = new BgpFlowSpecPrefix(destIpPrefix, srcIpPrefix);
if (operType == FlowSpecOperation.ADD) {
if (bgpFlowSpecDetails.routeDistinguisher() == null) {
flowSpecRibIn.add(prefix, bgpFlowSpecDetails);
} else {
flowSpecRibIn.add(bgpFlowSpecDetails.routeDistinguisher(), prefix, bgpFlowSpecDetails);
}
} else if (operType == FlowSpecOperation.DELETE) {
if (bgpFlowSpecDetails.routeDistinguisher() == null) {
flowSpecRibIn.delete(prefix);
} else {
flowSpecRibIn.delete(bgpFlowSpecDetails.routeDistinguisher(), prefix);
}
}
}
/**
* Updates NLRI identifier node in a tree separately based on afi and safi.
*
......@@ -447,13 +509,13 @@ public class BgpPeerImpl implements BgpPeer {
Constants.AFI_FLOWSPEC_VALUE,
Constants.VPN_SAFI_FLOWSPEC_VALUE);
if (isVpnCapabilitySet) {
Set<RouteDistinguisher> flowSpecKeys = vpnFlowSpecRibOut.vpnFlowSpecTree().keySet();
Set<RouteDistinguisher> flowSpecKeys = flowSpecRibOut.vpnFlowSpecTree().keySet();
for (RouteDistinguisher key : flowSpecKeys) {
Map<BgpFlowSpecPrefix, BgpFlowSpecDetails> fsTree = vpnFlowSpecRibOut.vpnFlowSpecTree().get(key);
Map<BgpFlowSpecPrefix, BgpFlowSpecDetails> fsTree = flowSpecRibOut.vpnFlowSpecTree().get(key);
Set<BgpFlowSpecPrefix> fsKeys = fsTree.keySet();
for (BgpFlowSpecPrefix fsKey : fsKeys) {
BgpFlowSpecDetails flowSpecDetails = vpnFlowSpecRibOut.flowSpecTree().get(fsKey);
BgpFlowSpecDetails flowSpecDetails = flowSpecRibOut.flowSpecTree().get(fsKey);
sendFlowSpecUpdateMessageToPeer(FlowSpecOperation.DELETE, flowSpecDetails);
}
}
......
......@@ -18,7 +18,7 @@ package org.onosproject.controller.impl;
import org.junit.Test;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onosproject.bgp.controller.impl.BgpFlowSpecRibOut;
import org.onosproject.bgp.controller.impl.BgpFlowSpecRib;
import org.onosproject.bgpio.protocol.flowspec.BgpFlowSpecDetails;
import org.onosproject.bgpio.protocol.flowspec.BgpFlowSpecPrefix;
import org.onosproject.bgpio.types.BgpFsOperatorValue;
......@@ -36,16 +36,16 @@ import static org.hamcrest.core.Is.is;
/**
* Test cases for BGP Selection Algorithm.
*/
public class BgpFlowSpecRibOutTest {
public class BgpFlowSpecRibTest {
/**
* Add flow specification to rib out.
* Add flow specification to rib.
*/
@Test
public void bgpFlowSpecRibOutTests1() {
public void bgpFlowSpecRibTests1() {
List<BgpValueType> flowSpecComponents = new LinkedList<>();
List<BgpFsOperatorValue> operatorValue = new ArrayList<>();
BgpFlowSpecRibOut ribOut = new BgpFlowSpecRibOut();
BgpFlowSpecRib rib = new BgpFlowSpecRib();
IpPrefix destinationPrefix = IpPrefix.valueOf(IpAddress.valueOf("10.0.1.1"), 32);
IpPrefix sourcePrefix = IpPrefix.valueOf(IpAddress.valueOf("10.0.1.2"), 32);
......@@ -60,20 +60,20 @@ public class BgpFlowSpecRibOutTest {
BgpFlowSpecDetails flowSpec = new BgpFlowSpecDetails(flowSpecComponents);
ribOut.add(prefix, flowSpec);
rib.add(prefix, flowSpec);
boolean isPresent = ribOut.flowSpecTree().containsKey(prefix);
boolean isPresent = rib.flowSpecTree().containsKey(prefix);
assertThat(isPresent, is(true));
}
/**
* Add and delete flow specification to rib out.
* Add and delete flow specification to rib.
*/
@Test
public void bgpFlowSpecRibOutTest2() {
public void bgpFlowSpecRibTest2() {
List<BgpValueType> flowSpecComponents = new LinkedList<>();
List<BgpFsOperatorValue> operatorValue = new ArrayList<>();
BgpFlowSpecRibOut ribOut = new BgpFlowSpecRibOut();
BgpFlowSpecRib rib = new BgpFlowSpecRib();
IpPrefix destinationPrefix = IpPrefix.valueOf(IpAddress.valueOf("10.0.1.1"), 32);
IpPrefix sourcePrefix = IpPrefix.valueOf(IpAddress.valueOf("10.0.1.2"), 32);
......@@ -87,26 +87,26 @@ public class BgpFlowSpecRibOutTest {
BgpFlowSpecDetails flowSpec = new BgpFlowSpecDetails(flowSpecComponents);
ribOut.add(prefix, flowSpec);
rib.add(prefix, flowSpec);
boolean isPresent = ribOut.flowSpecTree().containsKey(prefix);
boolean isPresent = rib.flowSpecTree().containsKey(prefix);
assertThat(isPresent, is(true));
ribOut.delete(prefix);
isPresent = ribOut.flowSpecTree().containsKey(prefix);
rib.delete(prefix);
isPresent = rib.flowSpecTree().containsKey(prefix);
assertThat(isPresent, is(false));
}
/**
* Add and delete flow specification with a specific VPN to rib out.
* Add and delete flow specification with a specific VPN to rib.
*/
@Test
public void bgpFlowSpecRibOutTest3() {
public void bgpFlowSpecRibTest3() {
List<BgpValueType> flowSpecComponents = new LinkedList<>();
List<BgpFsOperatorValue> operatorValue = new ArrayList<>();
RouteDistinguisher routeDistinguisher = new RouteDistinguisher(1);
BgpFlowSpecRibOut ribOut = new BgpFlowSpecRibOut();
BgpFlowSpecRib rib = new BgpFlowSpecRib();
IpPrefix destinationPrefix = IpPrefix.valueOf(IpAddress.valueOf("10.0.1.1"), 32);
IpPrefix sourcePrefix = IpPrefix.valueOf(IpAddress.valueOf("10.0.1.2"), 32);
......@@ -121,13 +121,13 @@ public class BgpFlowSpecRibOutTest {
BgpFlowSpecDetails flowSpec = new BgpFlowSpecDetails(flowSpecComponents);
ribOut.add(routeDistinguisher, prefix, flowSpec);
rib.add(routeDistinguisher, prefix, flowSpec);
boolean isPresent = ribOut.vpnFlowSpecTree().containsKey(routeDistinguisher);
boolean isPresent = rib.vpnFlowSpecTree().containsKey(routeDistinguisher);
assertThat(isPresent, is(true));
ribOut.delete(routeDistinguisher, prefix);
isPresent = ribOut.vpnFlowSpecTree().containsKey(routeDistinguisher);
rib.delete(routeDistinguisher, prefix);
isPresent = rib.vpnFlowSpecTree().containsKey(routeDistinguisher);
assertThat(isPresent, is(false));
}
}
......