Priyanka B
Committed by Gerrit Code Review

[ONOS] cherry pick from onos1.6 to master all defects merges

Change-Id: I0ff6595a55b1104cf59a270ac2b10a7f831f6555
......@@ -65,8 +65,6 @@ public class PceUpdatePathCommand extends AbstractShellCommand {
constrntList.add(BandwidthConstraint.of(Double.valueOf(bandwidth), DataRateUnit.valueOf("BPS")));
}
// Assign cost
if (cost != 0) {
// Cost validation
if ((cost < 1) || (cost > 2)) {
error("The cost attribute value is either IGP cost(1) or TE cost(2).");
......@@ -74,7 +72,6 @@ public class PceUpdatePathCommand extends AbstractShellCommand {
}
CostConstraint.Type costType = CostConstraint.Type.values()[cost - 1];
constrntList.add(CostConstraint.of(costType));
}
if (!service.updatePath(TunnelId.valueOf(id), constrntList)) {
error("Path updation failed.");
......
......@@ -269,7 +269,6 @@ public final class BasicPceccHandler {
* @param tunnel tunnel between ingress to egress
*/
public void releaseLabel(Tunnel tunnel) {
boolean isLastLabelToPush = false;
checkNotNull(labelRsrcService, LABEL_RESOURCE_SERVICE_NULL);
checkNotNull(pceStore, PCE_STORE_NULL);
......@@ -287,19 +286,14 @@ public final class BasicPceccHandler {
PortNumber inPort = lspLocalLabelInfo.inPort();
PortNumber outPort = lspLocalLabelInfo.outPort();
// Check whether this is last link label to push
if (!iterator.hasNext()) {
isLastLabelToPush = true;
}
// Push into device
if ((inLabelId != null) && (inPort != null)) {
installLocalLabelRule(deviceId, inLabelId, inPort, tunnel.tunnelId(), isLastLabelToPush,
installLocalLabelRule(deviceId, inLabelId, inPort, tunnel.tunnelId(), false,
Long.valueOf(LabelType.IN_LABEL.value), Objective.Operation.REMOVE);
}
if ((outLabelId != null) && (outPort != null)) {
installLocalLabelRule(deviceId, outLabelId, outPort, tunnel.tunnelId(), isLastLabelToPush,
installLocalLabelRule(deviceId, outLabelId, outPort, tunnel.tunnelId(), false,
Long.valueOf(LabelType.OUT_LABEL.value), Objective.Operation.REMOVE);
}
......@@ -331,7 +325,7 @@ public final class BasicPceccHandler {
}
// Install a rule for pushing local labels to the device which is specific to path.
private void installLocalLabelRule(DeviceId deviceId, LabelResourceId labelId,
private synchronized void installLocalLabelRule(DeviceId deviceId, LabelResourceId labelId,
PortNumber portNum, TunnelId tunnelId,
Boolean isBos, Long labelType,
Objective.Operation type) {
......
......@@ -110,14 +110,14 @@ import org.slf4j.LoggerFactory;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import static org.onosproject.incubator.net.tunnel.Tunnel.Type.MPLS;
import static org.onosproject.incubator.net.tunnel.Tunnel.State.ACTIVE;
import static org.onosproject.incubator.net.tunnel.Tunnel.State.INIT;
import static org.onosproject.incubator.net.tunnel.Tunnel.State.ESTABLISHED;
import static org.onosproject.incubator.net.tunnel.Tunnel.State.UNSTABLE;
import static org.onosproject.incubator.net.tunnel.Tunnel.Type.MPLS;
import static org.onosproject.pce.pceservice.LspType.WITH_SIGNALLING;
import static org.onosproject.pce.pceservice.LspType.SR_WITHOUT_SIGNALLING;
import static org.onosproject.pce.pceservice.LspType.WITHOUT_SIGNALLING_AND_WITHOUT_SR;
import static org.onosproject.pce.pceservice.PcepAnnotationKeys.BANDWIDTH;
import static org.onosproject.pce.pceservice.PcepAnnotationKeys.LOCAL_LSP_ID;
import static org.onosproject.pce.pceservice.PcepAnnotationKeys.LSP_SIG_TYPE;
......@@ -509,7 +509,7 @@ public class PceManager implements PceService {
}
if (existingBwValue != null) {
if (bwConstraintValue == 0) {
if (bwConstraintValue == 0 && bwConstraint != null) {
bwConstraintValue = existingBwValue.bps();
}
//If bandwidth constraints not specified , take existing bandwidth for shared bandwidth calculation
......@@ -621,6 +621,12 @@ public class PceManager implements PceService {
return false;
}
LspType lspType = LspType.valueOf(tunnel.annotations().value(LSP_SIG_TYPE));
// Release basic PCECC labels.
if (lspType == WITHOUT_SIGNALLING_AND_WITHOUT_SR) {
crHandler.releaseLabel(tunnel);
}
// 2. Call tunnel service.
return tunnelService.downTunnel(appId, tunnel.tunnelId());
}
......@@ -641,7 +647,7 @@ public class PceManager implements PceService {
*
* @return value of local LSP identifier
*/
private short getNextLocalLspId() {
private synchronized short getNextLocalLspId() {
// If there is any free id use it. Otherwise generate new id.
if (localLspIdFreeList.isEmpty()) {
return (short) localLspIdIdGen.getNewId();
......@@ -778,7 +784,7 @@ public class PceManager implements PceService {
bwToAllocate = 0;
if ((shBwConstraint != null) && (shBwConstraint.links().contains(link))) {
if (additionalBwValue != null) {
bwToAllocate = bandwidthConstraint - additionalBwValue;
bwToAllocate = additionalBwValue;
}
} else {
bwToAllocate = bandwidthConstraint;
......@@ -857,7 +863,12 @@ public class PceManager implements PceService {
// 1. Release old tunnel's bandwidth.
resourceService.release(pceStore.getTunnelInfo(oldTunnel.tunnelId()).tunnelConsumerId());
// 2. Release new tunnel's bandwidth
// 2. Release new tunnel's bandwidth, if new tunnel bandwidth is allocated
if (pceStore.getTunnelInfo(newTunnel.tunnelId()) == null) {
//If bandwidth for new tunnel is not allocated i,e 0 then no need to allocate
return;
}
ResourceConsumer consumer = pceStore.getTunnelInfo(newTunnel.tunnelId()).tunnelConsumerId();
resourceService.release(consumer);
......@@ -1148,6 +1159,22 @@ public class PceManager implements PceService {
}
}
//In CR case, release labels when new tunnel for it is updated.
if (lspType == WITHOUT_SIGNALLING_AND_WITHOUT_SR && tunnel.state() == ACTIVE
&& mastershipService.getLocalRole(tunnel.path().src().deviceId()) == MastershipRole.MASTER) {
Collection<Tunnel> tunnels = tunnelService.queryTunnel(tunnel.src(), tunnel.dst());
for (Tunnel t : tunnels) {
if (tunnel.annotations().value(PLSP_ID).equals(t.annotations().value(PLSP_ID))
&& !tunnel.annotations().value(LOCAL_LSP_ID)
.equals(t.annotations().value(LOCAL_LSP_ID))) {
// Release basic PCECC labels.
crHandler.releaseLabel(t);
break;
}
}
}
if (tunnel.state() == UNSTABLE) {
/*
* During LSP DB sync if PCC doesn't report LSP which was PCE initiated, it's state is turned into
......@@ -1183,23 +1210,16 @@ public class PceManager implements PceService {
if (lspType != WITH_SIGNALLING) {
localLspIdFreeList.add(Short.valueOf(tunnel.annotations().value(LOCAL_LSP_ID)));
}
// If not zero bandwidth, and delegated (initiated LSPs will also be delegated).
if (bwConstraintValue != 0) {
releaseBandwidth(event.subject());
// Release basic PCECC labels.
if (lspType == WITHOUT_SIGNALLING_AND_WITHOUT_SR) {
// Delete stored tunnel consumer id from PCE store (while still retaining label list.)
PceccTunnelInfo pceccTunnelInfo = pceStore.getTunnelInfo(tunnel.tunnelId());
pceccTunnelInfo.tunnelConsumerId(null);
if (mastershipService.getLocalRole(tunnel.path().src().deviceId()) == MastershipRole.MASTER) {
crHandler.releaseLabel(tunnel);
if (Float.parseFloat(tunnel.annotations().value(BANDWIDTH)) != 0
&& mastershipService.getLocalRole(tunnel.path().src().deviceId()) == MastershipRole.MASTER) {
releaseBandwidth(tunnel);
}
} else {
if (pceStore.getTunnelInfo(tunnel.tunnelId()) != null) {
pceStore.removeTunnelInfo(tunnel.tunnelId());
}
}
break;
default:
......
......@@ -44,6 +44,7 @@ import org.onosproject.pce.pceservice.constraint.CapabilityConstraint;
import org.onosproject.pce.pceservice.constraint.CostConstraint;
import org.onosproject.pce.pceservice.TunnelConsumerId;
import org.onosproject.pce.pceservice.LspType;
import org.onosproject.pce.pceservice.constraint.SharedBandwidthConstraint;
import org.onosproject.pce.pcestore.api.LspLocalLabelInfo;
import org.onosproject.pce.pcestore.api.PceStore;
import org.onosproject.store.serializers.KryoNamespaces;
......@@ -142,6 +143,7 @@ public class DistributedPceStore implements PceStore {
CostConstraint.class,
CostConstraint.Type.class,
BandwidthConstraint.class,
SharedBandwidthConstraint.class,
CapabilityConstraint.class,
CapabilityConstraint.CapabilityType.class,
LspType.class)
......
......@@ -115,8 +115,8 @@ public final class PceccTunnelInfo {
public String toString() {
return MoreObjects.toStringHelper(getClass())
.omitNullValues()
.add("DeviceLabelInfoList", lspLocalLabelInfoList.toString())
.add("TunnelConsumerId", tunnelConsumerId.toString())
.add("DeviceLabelInfoList", lspLocalLabelInfoList)
.add("TunnelConsumerId", tunnelConsumerId)
.toString();
}
}
......
......@@ -641,6 +641,8 @@ public class PceManagerTest {
build4RouterTopo(false, false, false, false, 5);
List<Constraint> constraints = new LinkedList<Constraint>();
CostConstraint costConstraint = new CostConstraint(TE_COST);
BandwidthConstraint bwConst = new BandwidthConstraint(Bandwidth.bps(3));
constraints.add(bwConst);
constraints.add(costConstraint);
pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, WITH_SIGNALLING);
......
......@@ -61,7 +61,7 @@ public class BgpMessageDecoder extends FrameDecoder {
BgpMessage message = reader.readFrom(buffer, bgpHeader);
msgList.add(message);
}
ctx.setAttachment(null);
return msgList;
} catch (Exception e) {
log.debug("Bgp protocol message decode error");
......
......@@ -279,7 +279,7 @@ public class PcepLabelUpdateVer1 implements PcepLabelUpdate {
}
llLabelList = labelDownload.getLabelList();
if (llLabelList == null) {
if (llLabelList == null || llLabelList.isEmpty()) {
throw new PcepParseException("Label list is mandatory object for Label Download.");
} else {
ListIterator<PcepLabelObject> listIterator = llLabelList.listIterator();
......
......@@ -63,8 +63,6 @@ import org.onosproject.bgpio.types.attr.BgpLinkAttrTeDefaultMetric;
import org.onosproject.core.CoreService;
import org.onosproject.incubator.net.resource.label.LabelResourceAdminService;
import org.onosproject.incubator.net.resource.label.LabelResourceId;
import org.onosproject.mastership.MastershipEvent;
import org.onosproject.mastership.MastershipListener;
import org.onosproject.mastership.MastershipService;
import org.onosproject.net.AnnotationKeys;
import org.onosproject.net.ConnectPoint;
......@@ -79,6 +77,8 @@ import org.onosproject.net.config.basics.BandwidthCapacity;
import org.onosproject.net.device.DefaultDeviceDescription;
import org.onosproject.net.device.DefaultPortDescription;
import org.onosproject.net.device.DeviceDescription;
import org.onosproject.net.device.DeviceEvent;
import org.onosproject.net.device.DeviceListener;
import org.onosproject.net.device.DeviceProvider;
import org.onosproject.net.device.DeviceProviderRegistry;
import org.onosproject.net.device.DeviceProviderService;
......@@ -140,7 +140,7 @@ public class BgpTopologyProvider extends AbstractProvider implements DeviceProvi
private DeviceProviderService deviceProviderService;
private LinkProviderService linkProviderService;
private InternalMastershipListener masterListener = new InternalMastershipListener();
private DeviceListener deviceListener = new InternalDeviceListener();
private InternalBgpProvider listener = new InternalBgpProvider();
private static final String UNKNOWN = "unknown";
public static final long IDENTIFIER_SET = 0x100000000L;
......@@ -169,7 +169,7 @@ public class BgpTopologyProvider extends AbstractProvider implements DeviceProvi
deviceProviderService = deviceProviderRegistry.register(this);
linkProviderService = linkProviderRegistry.register(this);
controller.addListener(listener);
mastershipService.addListener(masterListener);
deviceService.addListener(deviceListener);
controller.addLinkListener(listener);
}
......@@ -182,25 +182,28 @@ public class BgpTopologyProvider extends AbstractProvider implements DeviceProvi
linkProviderService = null;
controller.removeListener(listener);
controller.removeLinkListener(listener);
mastershipService.removeListener(masterListener);
deviceService.removeListener(deviceListener);
}
private class InternalMastershipListener implements MastershipListener {
private class InternalDeviceListener implements DeviceListener {
@Override
public void event(MastershipEvent event) {
if (event.type() == MastershipEvent.Type.MASTER_CHANGED) {
if (mastershipService.getMasterFor(event.subject()) != null) {
//Only for L3 device create label pool for that device
Device device = deviceService.getDevice(event.subject());
if (device == null) {
log.debug("Device {} doesn't exist", event.subject());
return;
public void event(DeviceEvent event) {
Device device = event.subject();
switch (event.type()) {
case DEVICE_ADDED:
if (!mastershipService.isLocalMaster(device.id())) {
break;
}
//Reserve device label pool for L3 devices
// Reserve device label pool for L3 devices
if (device.annotations().value(LSRID) != null) {
createDevicePool(event.subject());
}
createDevicePool(device.id());
}
break;
default:
break;
}
}
}
......@@ -460,6 +463,10 @@ public class BgpTopologyProvider extends AbstractProvider implements DeviceProvi
}
linkProviderService.linkVanished(linkDes);
linkDes = new DefaultLinkDescription(linkDes.dst(), linkDes.src(), Link.Type.DIRECT,
false, linkDes.annotations());
linkProviderService.linkVanished(linkDes);
}
}
......
......@@ -53,10 +53,7 @@ import org.onosproject.bgpio.types.LinkStateAttributes;
import org.onosproject.incubator.net.resource.label.LabelResourceAdminService;
import org.onosproject.incubator.net.resource.label.LabelResourceId;
import org.onosproject.incubator.net.resource.label.LabelResourcePool;
import org.onosproject.mastership.MastershipEvent;
import org.onosproject.mastership.MastershipListener;
import org.onosproject.mastership.MastershipServiceAdapter;
import org.onosproject.mastership.MastershipEvent.Type;
import org.onosproject.net.link.LinkServiceAdapter;
import org.onosproject.bgpio.types.LinkLocalRemoteIdentifiersTlv;
import org.onosproject.bgpio.types.RouteDistinguisher;
......@@ -68,8 +65,8 @@ import org.onosproject.bgpio.types.attr.BgpLinkAttrMaxLinkBandwidth;
import org.onosproject.bgpio.types.attr.BgpLinkAttrTeDefaultMetric;
import org.onosproject.bgpio.util.Constants;
import org.onosproject.cluster.NodeId;
import org.onosproject.cluster.RoleInfo;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.DefaultDevice;
import org.onosproject.net.DefaultLink;
import org.onosproject.net.Device;
......@@ -81,8 +78,9 @@ import org.onosproject.net.config.Config;
import org.onosproject.net.config.ConfigApplyDelegate;
import org.onosproject.net.config.ConfigFactory;
import org.onosproject.net.config.NetworkConfigRegistryAdapter;
import org.onosproject.net.config.basics.BandwidthCapacity;
import org.onosproject.net.device.DeviceDescription;
import org.onosproject.net.device.DeviceEvent;
import org.onosproject.net.device.DeviceListener;
import org.onosproject.net.device.DeviceProvider;
import org.onosproject.net.device.DeviceProviderRegistry;
import org.onosproject.net.device.DeviceProviderService;
......@@ -94,6 +92,7 @@ import org.onosproject.net.link.LinkProvider;
import org.onosproject.net.link.LinkProviderRegistry;
import org.onosproject.net.link.LinkProviderService;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.net.config.basics.BandwidthCapacity;
import org.onosproject.net.resource.Resource;
import org.onosproject.net.resource.ResourceAdminService;
import org.onosproject.net.resource.ResourceId;
......@@ -122,7 +121,7 @@ public class BgpTopologyProviderTest {
private MockNetConfigRegistryAdapter networkConfigService = new MockNetConfigRegistryAdapter();
private MockLabelResourceService labelResourceAdminService = new MockLabelResourceService();
private Map<DeviceId, Device> deviceMap = new HashMap<>();
private MastershipListener listener;
private DeviceListener listener;
@Before
public void startUp() throws TestUtilsException {
......@@ -134,7 +133,7 @@ public class BgpTopologyProviderTest {
provider.labelResourceAdminService = labelResourceAdminService;
provider.mastershipService = mastershipService;
provider.networkConfigService = networkConfigService;
listener = TestUtils.getField(provider, "masterListener");
listener = TestUtils.getField(provider, "deviceListener");
provider.activate();
assertThat("device provider should be registered", not(nodeRegistry.provider));
assertThat("link provider should be registered", not(linkRegistry.linkProvider));
......@@ -887,10 +886,14 @@ public class BgpTopologyProviderTest {
l.addNode(nodeNlri, details);
assertThat(nodeRegistry.connected.size(), is(1));
}
DefaultAnnotations.Builder newBuilder = DefaultAnnotations.builder();
newBuilder.set("lsrId", "1.1.1.1");
MastershipEvent event = new MastershipEvent(Type.MASTER_CHANGED, nodeRegistry.connected.iterator().next(),
new RoleInfo(NodeId.nodeId("Node1"), new LinkedList<>()));
Device device = new DefaultDevice(BgpTopologyProviderTest.providerId, nodeRegistry.connected.iterator().next(),
Device.Type.ROUTER, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, new ChassisId(), newBuilder.build());
DeviceEvent event = new DeviceEvent(DeviceEvent.Type.DEVICE_ADDED, device);
listener.event(event);
assertThat(labelResourceAdminService.resourcePool.keySet().size(), is(1));
}
......@@ -926,9 +929,16 @@ public class BgpTopologyProviderTest {
for (BgpNodeListener l : controller.nodeListener) {
l.addNode(nodeNlri, details);
assertThat(nodeRegistry.connected.size(), is(1));
// Check label resource reserved for that device
MastershipEvent event = new MastershipEvent(Type.MASTER_CHANGED, nodeRegistry.connected.iterator().next(),
new RoleInfo(NodeId.nodeId("Node1"), new LinkedList<>()));
DefaultAnnotations.Builder newBuilder = DefaultAnnotations.builder();
newBuilder.set("lsrId", "1.1.1.1");
Device device = new DefaultDevice(BgpTopologyProviderTest.providerId,
nodeRegistry.connected.iterator().next(), Device.Type.ROUTER, UNKNOWN,
UNKNOWN, UNKNOWN, UNKNOWN, new ChassisId(), newBuilder.build());
DeviceEvent event = new DeviceEvent(DeviceEvent.Type.DEVICE_ADDED, device);
listener.event(event);
assertThat(labelResourceAdminService.resourcePool.keySet().size(), is(1));
......@@ -988,8 +998,15 @@ public class BgpTopologyProviderTest {
l.addNode(nodeNlri, details);
assertThat(nodeRegistry.connected.size(), is(1));
//Check label resource reserved for that device
MastershipEvent event = new MastershipEvent(Type.MASTER_CHANGED, nodeRegistry.connected.iterator().next(),
new RoleInfo(NodeId.nodeId("Node1"), new LinkedList<>()));
DefaultAnnotations.Builder newBuilder = DefaultAnnotations.builder();
newBuilder.set("lsrId", "1.1.1.1");
Device device = new DefaultDevice(BgpTopologyProviderTest.providerId,
nodeRegistry.connected.iterator().next(), Device.Type.ROUTER,
UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, new ChassisId(), newBuilder.build());
DeviceEvent event = new DeviceEvent(DeviceEvent.Type.DEVICE_ADDED, device);
listener.event(event);
assertThat(labelResourceAdminService.resourcePool.keySet().size(), is(1));
l.addNode(remNodeNlri, details);
......
......@@ -449,8 +449,13 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
return;
}
// If delegation flag is set then only send update message[means delegated PCE can send update msg for that
// LSP].If annotation is null D flag is not set else it is set.
//PCInitiate tunnels are always have D flag set, else check for tunnels who are delegated via LspKey
if (pc.capability().statefulPceCapability()) {
if (tunnel.annotations().value(PCE_INIT) != null && tunnel.annotations().value(PCE_INIT).equals("true")) {
pcepUpdateTunnel(tunnel, path, pc);
} else {
// If delegation flag is set then only send update message[means delegated PCE can send update msg for
// that LSP. If annotation is null D flag is not set else it is set.
Short localLspId = 0;
for (Tunnel t : tunnels) {
if (!t.tunnelId().equals(tunnel.tunnelId()) && t.tunnelName().equals(tunnel.tunnelName())) {
......@@ -463,17 +468,14 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
return;
}
//PCInitiate tunnels are always have D flag set, else check for tunnels who are delegated via LspKey
if (pc.capability().statefulPceCapability()) {
if (tunnel.annotations().value(PCE_INIT) != null && tunnel.annotations().value(PCE_INIT).equals("true")) {
pcepUpdateTunnel(tunnel, path, pc);
} else if (pc.delegationInfo(
new LspKey(Integer.valueOf(tunnel.annotations().value(PLSP_ID)),
if (pc.delegationInfo(new LspKey(Integer.valueOf(tunnel.annotations().value(PLSP_ID)),
localLspId.shortValue())) != null) {
pcepUpdateTunnel(tunnel, path, pc);
}
}
}
}
@Override
public void updateTunnel(ElementId srcElement, Tunnel tunnel, Path path) {
......@@ -571,18 +573,22 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
return tunnelId;
}
private void tunnelUpdated(Tunnel tunnel, Path path) {
handleTunnelUpdate(tunnel, path);
private void tunnelUpdated(Tunnel tunnel, Path path, State tunnelState) {
handleTunnelUpdate(tunnel, path, tunnelState);
}
//Handles tunnel updated using tunnel admin service[specially to update annotations].
private void handleTunnelUpdate(Tunnel tunnel, Path path) {
private void handleTunnelUpdate(Tunnel tunnel, Path path, State tunnelState) {
if (tunnel.type() == MPLS) {
pcepTunnelApiMapper.removeFromCoreTunnelRequestQueue(tunnel.tunnelId());
tunnelAdminService.updateTunnel(tunnel, path);
TunnelDescription td = new DefaultTunnelDescription(tunnel.tunnelId(), tunnel.src(), tunnel.dst(),
tunnel.type(), tunnel.groupId(), tunnel.providerId(),
tunnel.tunnelName(), path, tunnel.resource(),
(SparseAnnotations) tunnel.annotations());
service.tunnelUpdated(td, tunnelState);
return;
}
......@@ -1238,14 +1244,12 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
tlv = new SymbolicPathNameTlv(tunnel.tunnelName().value().getBytes());
llOptionalTlv.add(tlv);
}
boolean delegated = (tunnel.annotations().value(DELEGATE) == null) ? false
: Boolean.valueOf(tunnel.annotations()
.value(DELEGATE));
boolean initiated = (tunnel.annotations().value(PCE_INIT) == null) ? false
: Boolean.valueOf(tunnel.annotations()
.value(PCE_INIT));
// build lsp object
PcepLspObject lspobj = pc.factory().buildLspObject().setAFlag(true)
.setPlspId(Integer.valueOf(tunnel.annotations().value(PLSP_ID)))
......@@ -1254,7 +1258,6 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
.setOptionalTlv(llOptionalTlv).build();
// build ero object
PcepEroObject eroobj = pc.factory().buildEroObject().setSubObjects(llSubObjects).build();
float iBandwidth = DEFAULT_BANDWIDTH_VALUE;
if (tunnel.annotations().value(BANDWIDTH) != null) {
iBandwidth = Float.parseFloat(tunnel.annotations().value(BANDWIDTH));
......@@ -1449,10 +1452,8 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
}
private SparseAnnotations getAnnotations(PcepLspObject lspObj, StatefulIPv4LspIdentifiersTlv ipv4LspIdenTlv,
float bandwidth, LspType lspType, String costType) {
String bandwidth, LspType lspType, String costType, boolean isPceInit) {
Builder builder = DefaultAnnotations.builder();
/*
* [RFC 5440] The absence of the METRIC object MUST be interpreted by the PCE as a path computation request
* for which no constraints need be applied to any of the metrics.
......@@ -1461,8 +1462,16 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
builder.set(COST_TYPE, costType);
}
if (isPceInit) {
builder.set(PCE_INIT, String.valueOf(isPceInit));
}
if (bandwidth != null) {
builder.set(BANDWIDTH, bandwidth);
}
SparseAnnotations annotations = builder
.set(BANDWIDTH, (new Float(bandwidth)).toString()).set(LSP_SIG_TYPE, lspType.name())
.set(LSP_SIG_TYPE, lspType.name())
.set(PCC_TUNNEL_ID, String.valueOf(ipv4LspIdenTlv.getTunnelId()))
.set(PLSP_ID, String.valueOf(lspObj.getPlspId()))
.set(LOCAL_LSP_ID, String.valueOf(ipv4LspIdenTlv.getLspId()))
......@@ -1502,7 +1511,6 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
log.error("ERO object is null in report message.");
return;
}
PcepAttribute attributes = msgPath.getPcepAttribute();
float bandwidth = 0;
int cost = 0;
......@@ -1529,6 +1537,7 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
bandwidth = attributes.getBandwidthObject().getBandwidth();
}
}
PcepLspObject lspObj = stateRpt.getLspObject();
List<Object> eroSubObjList = buildPathFromEroObj(eroObj, providerId);
List<Link> links = new ArrayList<>();
List<LabelResourceId> labels = new ArrayList<>();
......@@ -1539,18 +1548,20 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
labels.add(LabelResourceId.labelResourceId(((Integer) linkOrLabel).longValue()));
}
}
Path path = new DefaultPath(providerId, links, cost, EMPTY);
Path path = null;
if (!links.isEmpty()) {
path = new DefaultPath(providerId, links, cost, EMPTY);
} else if (!lspObj.getRFlag()) {
return;
}
NetworkResource labelStack = new DefaultLabelStack(labels);
// To carry PST TLV, SRP object can be present with value 0 even when PCRpt is not in response to any action
// from PCE.
PcepSrpObject srpObj = stateRpt.getSrpObject();
LspType lspType = getLspType(srpObj);
PcepLspObject lspObj = stateRpt.getLspObject();
ListIterator<PcepValueType> listTlvIterator = lspObj.getOptionalTlv().listIterator();
StatefulIPv4LspIdentifiersTlv ipv4LspIdenTlv = null;
SymbolicPathNameTlv pathNameTlv = null;
while (listTlvIterator.hasNext()) {
PcepValueType tlv = listTlvIterator.next();
switch (tlv.getType()) {
......@@ -1577,7 +1588,6 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
IpTunnelEndPoint tunnelEndPointDst = IpTunnelEndPoint
.ipTunnelPoint(IpAddress.valueOf(ipv4LspIdenTlv.getIpv4EgressAddress()));
Collection<Tunnel> tunnelQueryResult = tunnelService.queryTunnel(tunnelEndPointSrc, tunnelEndPointDst);
// Store delegation flag info and that LSP info because only delegated PCE sends update message
// Storing if D flag is set, if not dont store. while checking whether delegation if annotation for D flag
// not present then non-delegated , if present it is delegated.
......@@ -1586,6 +1596,7 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
new LspKey(lspObj.getPlspId(), ipv4LspIdenTlv.getLspId()), lspObj.getDFlag());
}
Tunnel tunnel = null;
SparseAnnotations oldTunnelAnnotations = null;
// Asynchronous status change message from PCC for LSP reported earlier.
for (Tunnel tunnelObj : tunnelQueryResult) {
if (tunnelObj.annotations().value(PLSP_ID) == null) {
......@@ -1603,13 +1614,17 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
}
continue;
}
if ((Integer.valueOf(tunnelObj.annotations().value(PLSP_ID)) == lspObj.getPlspId()) && (Integer
if ((Integer.valueOf(tunnelObj.annotations().value(PLSP_ID)) == lspObj.getPlspId())) {
if ((Integer
.valueOf(tunnelObj.annotations().value(LOCAL_LSP_ID)) == ipv4LspIdenTlv.getLspId())) {
tunnel = tunnelObj;
break;
}
if ((Integer
.valueOf(tunnelObj.annotations().value(LOCAL_LSP_ID)) != ipv4LspIdenTlv.getLspId())) {
oldTunnelAnnotations = (SparseAnnotations) tunnelObj.annotations();
}
}
}
DefaultTunnelDescription td;
SparseAnnotations annotations = null;
State tunnelState = PcepLspStatus.getTunnelStatusFromLspStatus(PcepLspStatus.values()[lspObj.getOFlag()]);
......@@ -1621,24 +1636,27 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
*/
return;
}
DeviceId deviceId = getDevice(pccId);
if (deviceId == null) {
log.error("Ingress deviceId not found");
return;
}
annotations = getAnnotations(lspObj, ipv4LspIdenTlv, bandwidth, lspType, costType);
String tempBandwidth = null;
String temoCostType = null;
if (oldTunnelAnnotations != null) {
tempBandwidth = oldTunnelAnnotations.value(BANDWIDTH);
temoCostType = oldTunnelAnnotations.value(COST_TYPE);
}
annotations = getAnnotations(lspObj, ipv4LspIdenTlv, tempBandwidth, lspType,
temoCostType, lspObj.getCFlag());
td = new DefaultTunnelDescription(null, tunnelEndPointSrc, tunnelEndPointDst, MPLS, new DefaultGroupId(
0), providerId, TunnelName.tunnelName(new String(pathNameTlv.getValue())), path, labelStack,
annotations);
// Do not support PCC initiated LSP after LSP DB sync is completed.
if (!lspObj.getSFlag() && !lspObj.getCFlag()) {
log.error("Received PCC initiated LSP while not in sync.");
return;
}
/*
* If ONOS instance is master for PCC then set delegated flag as annotation and add the tunnel to store.
* Because all LSPs need not be delegated, hence mastership for the PCC is confirmed whereas not the
......@@ -1670,43 +1688,54 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
pcepTunnelApiMapper.addToTunnelIdMap(pcepTunnelData);
} else if (!mastershipService.isLocalMaster(deviceId) && lspObj.getDFlag()) {
//Start timer then update the tunnel with D flag
tunnelUpdateInDelegatedCase(pccId, annotations, td, providerId);
tunnelUpdateInDelegatedCase(pccId, annotations, td, providerId, tunnelState, ipv4LspIdenTlv);
}
return;
}
//delegated owner will update can be a master or non-master
if (lspObj.getDFlag()) {
if (tunnel.annotations().value(BANDWIDTH) != null) {
bandwidth = Float.parseFloat(tunnel.annotations().value(BANDWIDTH));
if (lspObj.getDFlag() && !lspObj.getRFlag()) {
tunnelUpdateForDelegatedLsp(tunnel, lspObj,
lspType, tunnelState, pccId, labelStack, ipv4LspIdenTlv);
return;
}
removeOrUpdatetunnel(tunnel, lspObj, providerId, tunnelState, ipv4LspIdenTlv);
}
private void tunnelUpdateForDelegatedLsp(Tunnel tunnel, PcepLspObject lspObj,
LspType lspType, State tunnelState, PccId pccId,
NetworkResource labelStack,
StatefulIPv4LspIdentifiersTlv ipv4LspIdenTlv) {
SparseAnnotations annotations = null;
DefaultTunnelDescription td;
boolean isPceInit = tunnel.annotations().value(PCE_INIT) == null ? false :
Boolean.valueOf((tunnel.annotations().value(PCE_INIT))).booleanValue();
annotations = getAnnotations(lspObj, ipv4LspIdenTlv,
bandwidth, lspType,
tunnel.annotations().value(COST_TYPE));
td = new DefaultTunnelDescription(null, tunnelEndPointSrc, tunnelEndPointDst, MPLS, new DefaultGroupId(
0), providerId, TunnelName.tunnelName(new String(pathNameTlv.getValue())),
tunnel.annotations().value(BANDWIDTH), lspType,
tunnel.annotations().value(COST_TYPE), isPceInit);
td = new DefaultTunnelDescription(null, tunnel.src(), tunnel.dst(), MPLS, new DefaultGroupId(
0), tunnel.providerId(), tunnel.tunnelName(),
tunnel.path(), labelStack, annotations);
tunnelUpdateInDelegatedCase(pccId, annotations, td, providerId);
}
removeOrUpdatetunnel(tunnel, pccId, lspObj, providerId, tunnelState);
return;
tunnelUpdateInDelegatedCase(pccId, annotations, td, tunnel.providerId(), tunnelState, ipv4LspIdenTlv);
}
private void removeOrUpdatetunnel(Tunnel tunnel, PccId pccId, PcepLspObject lspObj, ProviderId providerId,
State tunnelState) {
private void removeOrUpdatetunnel(Tunnel tunnel, PcepLspObject lspObj, ProviderId providerId,
State tunnelState, StatefulIPv4LspIdentifiersTlv ipv4LspIdenTlv) {
DefaultTunnelDescription td = new DefaultTunnelDescription(tunnel.tunnelId(), tunnel.src(), tunnel.dst(),
tunnel.type(), tunnel.groupId(), providerId, tunnel.tunnelName(), tunnel.path(),
(SparseAnnotations) tunnel.annotations());
if (lspObj.getRFlag()) {
tunnelRemoved(td);
} else {
PcepTunnelData pcepTunnelData = new PcepTunnelData(tunnel, tunnel.path(), LSP_STATE_RPT);
pcepTunnelData.setStatefulIpv4IndentifierTlv(ipv4LspIdenTlv);
pcepTunnelApiMapper.addToTunnelIdMap(pcepTunnelData);
tunnelUpdated(td, tunnelState);
}
}
private void tunnelUpdateInDelegatedCase(PccId pccId, SparseAnnotations annotations,
DefaultTunnelDescription td, ProviderId providerId) {
DefaultTunnelDescription td, ProviderId providerId, State tunnelState,
StatefulIPv4LspIdentifiersTlv ipv4LspIdentifiersTlv) {
//Wait for 2sec then query tunnel based on ingress PLSP-ID and local LSP-ID
/*
......@@ -1717,7 +1746,7 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
// Thread is started after 2 seconds first time later periodically after 2 seconds to update the tunnel
executor.scheduleAtFixedRate(new UpdateDelegation(td, providerId, annotations, pccId,
executor), DELAY, DELAY, TimeUnit.SECONDS);
executor, tunnelState, ipv4LspIdentifiersTlv), DELAY, DELAY, TimeUnit.SECONDS);
}
/**
......@@ -1733,7 +1762,7 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
LinkedList<PcepValueType> llSubObj = eroObj.getSubObjects();
if (0 == llSubObj.size()) {
log.error("ERO in report message does not have hop information");
return null;
return new ArrayList<>();
}
ListIterator<PcepValueType> tlvIterator = llSubObj.listIterator();
......@@ -1787,10 +1816,29 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
if (srEroSubObj.getSt() == PcepNaiIpv4Adjacency.ST_TYPE) {
PcepNaiIpv4Adjacency nai = (PcepNaiIpv4Adjacency) (srEroSubObj.getNai());
IpAddress srcIp = IpAddress.valueOf(nai.getLocalIpv4Addr());
src = new ConnectPoint(IpElementId.ipElement(srcIp), PortNumber.portNumber(0));
IpAddress dstIp = IpAddress.valueOf(nai.getRemoteIpv4Addr());
dst = new ConnectPoint(IpElementId.ipElement(dstIp), PortNumber.portNumber(0));
int srcIp = nai.getLocalIpv4Addr();
int dstIp = nai.getRemoteIpv4Addr();
Iterable<Link> links = linkService.getActiveLinks();
for (Link l : links) {
long lSrc = l.src().port().toLong();
long lDst = l.dst().port().toLong();
if (lSrc == srcIp) {
src = l.src();
} else if (lDst == srcIp) {
src = l.dst();
}
if (lSrc == dstIp) {
dst = l.src();
} else if (lDst == dstIp) {
dst = l.dst();
}
if (src != null && dst != null) {
break;
}
}
if (src == null || dst == null) {
return new ArrayList<>();
}
Link link = DefaultLink.builder()
.providerId(providerId)
.src(src)
......@@ -1803,7 +1851,6 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
// the other sub objects are not required
}
}
return subObjList;
}
......@@ -1861,7 +1908,6 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
return service.tunnelQueryById(tunnelId);
}
private DeviceId getDevice(PccId pccId) {
// Get lsrId of the PCEP client from the PCC ID. Session info is based on lsrID.
IpAddress lsrId = pccId.ipAddress();
......@@ -1888,6 +1934,8 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
SparseAnnotations annotations;
PccId pccId;
ScheduledExecutorService executor;
State tunnelState;
StatefulIPv4LspIdentifiersTlv ipv4LspIdentifiersTlv;
/**
* Creates an instance of UpdateDelegation.
......@@ -1899,12 +1947,15 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
* @param executor service of delegated owner
*/
public UpdateDelegation(DefaultTunnelDescription td, ProviderId providerId, SparseAnnotations annotations,
PccId pccId, ScheduledExecutorService executor) {
PccId pccId, ScheduledExecutorService executor, State tunnelState,
StatefulIPv4LspIdentifiersTlv ipv4LspIdentifiersTlv) {
this.td = td;
this.providerId = providerId;
this.annotations = annotations;
this.pccId = pccId;
this.executor = executor;
this.tunnelState = tunnelState;
this.ipv4LspIdentifiersTlv = ipv4LspIdentifiersTlv;
}
//Temporary using annotations later will use projection/network config service
......@@ -1930,7 +1981,11 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
if (tempTunnelId != null) {
Tunnel tunnel = new DefaultTunnel(providerId, td.src(), td.dst(), MPLS, new DefaultGroupId(0),
tempTunnelId, td.tunnelName(), td.path(), annotations);
tunnelUpdated(tunnel, td.path());
PcepTunnelData pcepTunnelData = new PcepTunnelData(tunnel, tunnel.path(), LSP_STATE_RPT);
pcepTunnelData.setStatefulIpv4IndentifierTlv(ipv4LspIdentifiersTlv);
pcepTunnelData.setLspDFlag(Boolean.valueOf(tunnel.annotations().value(DELEGATE)));
pcepTunnelApiMapper.addToTunnelIdMap(pcepTunnelData);
tunnelUpdated(tunnel, td.path(), tunnelState);
executor.shutdown();
try {
executor.awaitTermination(WAIT_TIME, TimeUnit.SECONDS);
......
......@@ -36,6 +36,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;
......@@ -237,6 +238,17 @@ public class PcepTunnelAddedTest {
@Override
public void tunnelUpdated(TunnelDescription tunnel, State state) {
TunnelId id = TunnelId.valueOf(String.valueOf(++tunnelIdCounter));
Tunnel storedTunnel = new DefaultTunnel(ProviderId.NONE,
tunnel.src(), tunnel.dst(),
tunnel.type(),
tunnel.groupId(),
id,
tunnel.tunnelName(),
tunnel.path(),
tunnel.resource(),
tunnel.annotations());
tunnelService.tunnelIdAsKeyStore.put(id, storedTunnel);
}
@Override
......@@ -592,8 +604,11 @@ public class PcepTunnelAddedTest {
controller.processClientMessage(PccId.pccId(IpAddress.valueOf("1.1.1.1")), message);
TimeUnit.MILLISECONDS.sleep(4000);
assertThat(registry.tunnelIdCounter, is((long) 1));
assertThat(tunnelService.tunnelIdAsKeyStore.values().iterator().next().annotations().value(DELEGATE),
assertThat(registry.tunnelIdCounter, is((long) 2));
Iterator<Tunnel> iterator = tunnelService.tunnelIdAsKeyStore.values().iterator();
iterator.next();
assertThat(iterator.next().annotations().value(DELEGATE),
is("true"));
}
......