use of org.onlab.util.Identifier in project onos by opennetworkinglab.
the class LinkCollectionIntentFlowObjectiveCompiler method compile.
@Override
public List<Intent> compile(LinkCollectionIntent intent, List<Intent> installable) {
SetMultimap<DeviceId, PortNumber> inputPorts = HashMultimap.create();
SetMultimap<DeviceId, PortNumber> outputPorts = HashMultimap.create();
Map<ConnectPoint, Identifier<?>> labels = ImmutableMap.of();
Optional<EncapsulationConstraint> encapConstraint = this.getIntentEncapConstraint(intent);
computePorts(intent, inputPorts, outputPorts);
if (encapConstraint.isPresent()) {
labels = labelAllocator.assignLabelToPorts(intent.links(), intent.key(), encapConstraint.get().encapType(), encapConstraint.get().suggestedIdentifier());
}
ImmutableList.Builder<Intent> intentList = ImmutableList.builder();
if (this.isDomainProcessingEnabled(intent)) {
intentList.addAll(this.getDomainIntents(intent, domainService));
}
List<Objective> objectives = new ArrayList<>();
List<DeviceId> devices = new ArrayList<>();
for (DeviceId deviceId : outputPorts.keySet()) {
// add only objectives that are not inside of a domain
if (LOCAL.equals(domainService.getDomain(deviceId))) {
List<Objective> deviceObjectives = createRules(intent, deviceId, inputPorts.get(deviceId), outputPorts.get(deviceId), labels);
deviceObjectives.forEach(objective -> {
objectives.add(objective);
devices.add(deviceId);
});
}
}
// if any objectives have been created
if (!objectives.isEmpty()) {
intentList.add(new FlowObjectiveIntent(appId, intent.key(), devices, objectives, intent.resources(), intent.resourceGroup()));
}
return intentList.build();
}
use of org.onlab.util.Identifier in project onos by opennetworkinglab.
the class PathCompiler method manageVlanEncap.
/**
* Creates the flow rules for the path intent using VLAN
* encapsulation.
*
* @param creator the flowrules creator
* @param flows the list of flows to fill
* @param devices the devices on the path
* @param intent the PathIntent to compile
*/
private void manageVlanEncap(PathCompilerCreateFlow<T> creator, List<T> flows, List<DeviceId> devices, PathIntent intent) {
Set<Link> linksSet = Sets.newConcurrentHashSet();
for (int i = 1; i <= intent.path().links().size() - 2; i++) {
linksSet.add(intent.path().links().get(i));
}
Map<LinkKey, Identifier<?>> vlanIds = labelAllocator.assignLabelToLinks(linksSet, intent.key(), EncapsulationType.VLAN);
Iterator<Link> links = intent.path().links().iterator();
Link srcLink = links.next();
Link link = links.next();
// Ingress traffic
VlanId vlanId = (VlanId) vlanIds.get(linkKey(link));
if (vlanId == null) {
throw new IntentCompilationException(ERROR_VLAN + link);
}
VlanId prevVlanId = vlanId;
Optional<VlanIdCriterion> vlanCriterion = intent.selector().criteria().stream().filter(criterion -> criterion.type() == Criterion.Type.VLAN_VID).map(criterion -> (VlanIdCriterion) criterion).findAny();
// Push VLAN if selector does not include VLAN
TrafficTreatment.Builder treatBuilder = DefaultTrafficTreatment.builder();
if (!vlanCriterion.isPresent()) {
treatBuilder.pushVlan();
}
// Tag the traffic with the new encapsulation VLAN
treatBuilder.setVlanId(vlanId);
creator.createFlow(intent.selector(), treatBuilder.build(), srcLink.dst(), link.src(), intent.priority(), true, flows, devices);
ConnectPoint prev = link.dst();
while (links.hasNext()) {
link = links.next();
if (links.hasNext()) {
// Transit traffic
VlanId egressVlanId = (VlanId) vlanIds.get(linkKey(link));
if (egressVlanId == null) {
throw new IntentCompilationException(ERROR_VLAN + link);
}
TrafficSelector transitSelector = DefaultTrafficSelector.builder().matchInPort(prev.port()).matchVlanId(prevVlanId).build();
TrafficTreatment.Builder transitTreat = DefaultTrafficTreatment.builder();
// Set the new vlanId only if the previous one is different
if (!prevVlanId.equals(egressVlanId)) {
transitTreat.setVlanId(egressVlanId);
}
creator.createFlow(transitSelector, transitTreat.build(), prev, link.src(), intent.priority(), true, flows, devices);
/* For the next hop we have to remember
* the previous egress VLAN id and the egress
* node
*/
prevVlanId = egressVlanId;
prev = link.dst();
} else {
// Egress traffic
TrafficSelector egressSelector = DefaultTrafficSelector.builder().matchInPort(prev.port()).matchVlanId(prevVlanId).build();
TrafficTreatment.Builder egressTreat = DefaultTrafficTreatment.builder(intent.treatment());
Optional<L2ModificationInstruction.ModVlanIdInstruction> modVlanIdInstruction = intent.treatment().allInstructions().stream().filter(instruction -> instruction instanceof L2ModificationInstruction.ModVlanIdInstruction).map(x -> (L2ModificationInstruction.ModVlanIdInstruction) x).findAny();
Optional<L2ModificationInstruction.ModVlanHeaderInstruction> popVlanInstruction = intent.treatment().allInstructions().stream().filter(instruction -> instruction instanceof L2ModificationInstruction.ModVlanHeaderInstruction).map(x -> (L2ModificationInstruction.ModVlanHeaderInstruction) x).findAny();
if (!modVlanIdInstruction.isPresent() && !popVlanInstruction.isPresent()) {
if (vlanCriterion.isPresent()) {
egressTreat.setVlanId(vlanCriterion.get().vlanId());
} else {
egressTreat.popVlan();
}
}
creator.createFlow(egressSelector, egressTreat.build(), prev, link.src(), intent.priority(), true, flows, devices);
}
}
}
use of org.onlab.util.Identifier in project onos by opennetworkinglab.
the class PathCompiler method manageMplsEncap.
/**
* Creates the flow rules for the path intent using MPLS
* encapsulation.
*
* @param creator the flowrules creator
* @param flows the list of flows to fill
* @param devices the devices on the path
* @param intent the PathIntent to compile
*/
private void manageMplsEncap(PathCompilerCreateFlow<T> creator, List<T> flows, List<DeviceId> devices, PathIntent intent) {
Set<Link> linksSet = Sets.newConcurrentHashSet();
for (int i = 1; i <= intent.path().links().size() - 2; i++) {
linksSet.add(intent.path().links().get(i));
}
Map<LinkKey, Identifier<?>> mplsLabels = labelAllocator.assignLabelToLinks(linksSet, intent.key(), EncapsulationType.MPLS);
Iterator<Link> links = intent.path().links().iterator();
Link srcLink = links.next();
Link link = links.next();
// List of flow rules to be installed
// Ingress traffic
MplsLabel mplsLabel = (MplsLabel) mplsLabels.get(linkKey(link));
if (mplsLabel == null) {
throw new IntentCompilationException(ERROR_MPLS + link);
}
MplsLabel prevMplsLabel = mplsLabel;
Optional<MplsCriterion> mplsCriterion = intent.selector().criteria().stream().filter(criterion -> criterion.type() == Criterion.Type.MPLS_LABEL).map(criterion -> (MplsCriterion) criterion).findAny();
// Push MPLS if selector does not include MPLS
TrafficTreatment.Builder treatBuilder = DefaultTrafficTreatment.builder();
if (!mplsCriterion.isPresent()) {
treatBuilder.pushMpls();
}
// Tag the traffic with the new encapsulation MPLS label
treatBuilder.setMpls(mplsLabel);
creator.createFlow(intent.selector(), treatBuilder.build(), srcLink.dst(), link.src(), intent.priority(), true, flows, devices);
ConnectPoint prev = link.dst();
while (links.hasNext()) {
link = links.next();
if (links.hasNext()) {
// Transit traffic
MplsLabel transitMplsLabel = (MplsLabel) mplsLabels.get(linkKey(link));
if (transitMplsLabel == null) {
throw new IntentCompilationException(ERROR_MPLS + link);
}
TrafficSelector transitSelector = DefaultTrafficSelector.builder().matchInPort(prev.port()).matchEthType(Ethernet.MPLS_UNICAST).matchMplsLabel(prevMplsLabel).build();
TrafficTreatment.Builder transitTreat = DefaultTrafficTreatment.builder();
// Set the new MPLS label only if the previous one is different
if (!prevMplsLabel.equals(transitMplsLabel)) {
transitTreat.setMpls(transitMplsLabel);
}
creator.createFlow(transitSelector, transitTreat.build(), prev, link.src(), intent.priority(), true, flows, devices);
prevMplsLabel = transitMplsLabel;
prev = link.dst();
} else {
TrafficSelector.Builder egressSelector = DefaultTrafficSelector.builder().matchInPort(prev.port()).matchEthType(Ethernet.MPLS_UNICAST).matchMplsLabel(prevMplsLabel);
TrafficTreatment.Builder egressTreat = DefaultTrafficTreatment.builder(intent.treatment());
// than selector needs to match any VlanId
for (Instruction instruct : intent.treatment().allInstructions()) {
if (instruct instanceof L2ModificationInstruction) {
L2ModificationInstruction l2Mod = (L2ModificationInstruction) instruct;
if (l2Mod.subtype() == L2ModificationInstruction.L2SubType.VLAN_PUSH) {
break;
}
if (l2Mod.subtype() == L2ModificationInstruction.L2SubType.VLAN_POP || l2Mod.subtype() == L2ModificationInstruction.L2SubType.VLAN_ID) {
egressSelector.matchVlanId(VlanId.ANY);
}
}
}
if (mplsCriterion.isPresent()) {
egressTreat.setMpls(mplsCriterion.get().label());
} else {
egressTreat.popMpls(getEthType(intent.selector()));
}
creator.createFlow(egressSelector.build(), egressTreat.build(), prev, link.src(), intent.priority(), true, flows, devices);
}
}
}
use of org.onlab.util.Identifier in project onos by opennetworkinglab.
the class LabelAllocatorTest method noLabelsTest.
/**
* To test the developed algorithms when there are no labels.
*/
@Test
public void noLabelsTest() {
// Verify the first fit behavior with NONE optimization
this.allocator.setLabelSelection(firstFit);
assertThat(this.allocator.getLabelSelection(), instanceOf(FirstFitSelection.class));
// It has to be an instance of NONE
assertEquals(this.allocator.getOptLabelSelection(), LabelAllocator.OptimizationBehavior.NONE);
// We change the available Ids
this.resourceService.availableVlanLabels = ImmutableSet.of((short) 10);
// Enable filtering of the reservation
this.resourceService.filterAssignment = true;
// We test the behavior for VLAN
Map<LinkKey, Identifier<?>> allocation = this.allocator.assignLabelToLinks(ImmutableSet.copyOf(links.subList(1, 3)), IntentId.valueOf(idGenerator.getNewId()), EncapsulationType.VLAN);
Identifier<?> id = allocation.get(LinkKey.linkKey(d1p1, d3p1));
// value has to be a VlanId
assertThat(id, instanceOf(VlanId.class));
// value should not be a forbidden value
VlanId label = (VlanId) id;
assertTrue(VlanId.NO_VID < label.toShort() && label.toShort() < VlanId.MAX_VLAN);
// Next hop
id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
assertThat(id, instanceOf(VlanId.class));
label = (VlanId) id;
assertTrue(VlanId.NO_VID < label.toShort() && label.toShort() < VlanId.MAX_VLAN);
// No labels are available, reservation is not possible
allocation = this.allocator.assignLabelToLinks(ImmutableSet.copyOf(links.subList(1, 3)), IntentId.valueOf(idGenerator.getNewId()), EncapsulationType.VLAN);
id = allocation.get(LinkKey.linkKey(d1p1, d3p1));
// value has to be null
assertNull(id);
id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
// value has to be null
assertNull(id);
// Verify the random behavior with NONE_SWAP optimization
this.allocator.setLabelSelection(random);
assertThat(this.allocator.getLabelSelection(), instanceOf(RandomSelection.class));
// Change to NO_SWAP
this.allocator.setOptLabelSelection(noswap);
assertEquals(this.allocator.getOptLabelSelection(), LabelAllocator.OptimizationBehavior.NO_SWAP);
// We change the available Ids
this.resourceService.availableMplsLabels = ImmutableSet.of(2000);
// Enable filtering of the reservation
this.resourceService.filterAssignment = true;
// We test the behavior for MPLS
allocation = this.allocator.assignLabelToLinks(ImmutableSet.copyOf(links.subList(1, 3)), IntentId.valueOf(idGenerator.getNewId()), EncapsulationType.MPLS);
id = allocation.get(LinkKey.linkKey(d1p1, d3p1));
// value has to be a Mplslabel
assertThat(id, instanceOf(MplsLabel.class));
// value should not be a forbidden value
MplsLabel mplsLabel = (MplsLabel) id;
assertTrue(0 <= mplsLabel.toInt() && mplsLabel.toInt() <= MplsLabel.MAX_MPLS);
id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
assertThat(id, instanceOf(MplsLabel.class));
mplsLabel = (MplsLabel) id;
assertTrue(0 <= mplsLabel.toInt() && mplsLabel.toInt() <= MplsLabel.MAX_MPLS);
// No labels are available, reservation is not possible
allocation = this.allocator.assignLabelToLinks(ImmutableSet.copyOf(links.subList(1, 3)), IntentId.valueOf(idGenerator.getNewId()), EncapsulationType.MPLS);
id = allocation.get(LinkKey.linkKey(d1p1, d3p1));
// value has to be null
assertNull(id);
id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
// value has to be null
assertNull(id);
// Verify the first fit behavior with MIN optimization
this.allocator.setLabelSelection(firstFit);
assertThat(this.allocator.getLabelSelection(), instanceOf(FirstFitSelection.class));
// Change to MIN_SWAP
this.allocator.setOptLabelSelection(minswap);
assertEquals(this.allocator.getOptLabelSelection(), LabelAllocator.OptimizationBehavior.MIN_SWAP);
// We change the available Ids
this.resourceService.availableVlanLabels = ImmutableSet.of((short) 11);
// Enable filtering of the reservation
this.resourceService.filterAssignment = true;
// We test the behavior for VLAN
allocation = this.allocator.assignLabelToLinks(ImmutableSet.copyOf(links.subList(1, 3)), IntentId.valueOf(idGenerator.getNewId()), EncapsulationType.VLAN);
id = allocation.get(LinkKey.linkKey(d1p1, d3p1));
// value has to be a VlanId
assertThat(id, instanceOf(VlanId.class));
// value should not be a forbidden value
label = (VlanId) id;
assertTrue(VlanId.NO_VID < label.toShort() && label.toShort() < VlanId.MAX_VLAN);
// Next hop
id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
assertThat(id, instanceOf(VlanId.class));
label = (VlanId) id;
assertTrue(VlanId.NO_VID < label.toShort() && label.toShort() < VlanId.MAX_VLAN);
// No labels are available, reservation is not possible
allocation = this.allocator.assignLabelToLinks(ImmutableSet.copyOf(links.subList(1, 3)), IntentId.valueOf(idGenerator.getNewId()), EncapsulationType.VLAN);
id = allocation.get(LinkKey.linkKey(d1p1, d3p1));
// value has to be null
assertNull(id);
id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
// value has to be null
assertNull(id);
}
use of org.onlab.util.Identifier in project onos by opennetworkinglab.
the class LabelAllocatorTest method testFirstFitBehaviorNone.
/**
* To test the first fit behavior. Using NONE optimization
*/
@Test
public void testFirstFitBehaviorNone() {
// We change to FirstFit and we test the change
this.allocator.setLabelSelection(firstFit);
assertThat(this.allocator.getLabelSelection(), instanceOf(FirstFitSelection.class));
// It has to be an instance of NONE
assertEquals(this.allocator.getOptLabelSelection(), LabelAllocator.OptimizationBehavior.NONE);
// Filter reservations
this.resourceService.filterAssignment = true;
// We change the available Ids
this.resourceService.availableVlanLabels = ImmutableSet.of((short) 1, (short) 20, (short) 100);
// First allocation on a subset of links
Map<LinkKey, Identifier<?>> allocation = this.allocator.assignLabelToLinks(ImmutableSet.copyOf(links.subList(2, 3)), IntentId.valueOf(idGenerator.getNewId()), EncapsulationType.VLAN);
Identifier<?> id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
// value has to be a Vlan Id
assertThat(id, instanceOf(VlanId.class));
// value should not be a forbidden value
VlanId vlanId = (VlanId) id;
assertTrue(VlanId.NO_VID < vlanId.toShort() && vlanId.toShort() < VlanId.MAX_VLAN);
// We test the behavior for VLAN
allocation = this.allocator.assignLabelToLinks(ImmutableSet.copyOf(links.subList(1, 3)), IntentId.valueOf(idGenerator.getNewId()), EncapsulationType.VLAN);
id = allocation.get(LinkKey.linkKey(d1p1, d3p1));
assertThat(id, instanceOf(VlanId.class));
vlanId = (VlanId) id;
assertTrue(VlanId.NO_VID < vlanId.toShort() && vlanId.toShort() < VlanId.MAX_VLAN);
id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
assertThat(id, instanceOf(VlanId.class));
vlanId = (VlanId) id;
assertTrue(VlanId.NO_VID < vlanId.toShort() && vlanId.toShort() < VlanId.MAX_VLAN);
}
Aggregations