use of org.onosproject.net.flowobjective.NextObjective in project onos by opennetworkinglab.
the class LinkCollectionIntentFlowObjectiveCompilerTest method testFilteredConnectPointForMpWithEncap.
/**
* Multi point to single point intent with filtered connect point.
* Scenario is the follow:
*
* -1 of1 2-1 of2 2-1 of4 2-
* 3
* -1 of3 2---/
* We test the proper compilation constraint of mp2sp
* with encapsulation, trivial selector, empty treatment and points.
*/
@Test
public void testFilteredConnectPointForMpWithEncap() throws Exception {
LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
Set<Link> testLinks = ImmutableSet.of(DefaultLink.builder().providerId(PID).src(of1p2).dst(of2p1).type(DIRECT).build(), DefaultLink.builder().providerId(PID).src(of3p2).dst(of2p3).type(DIRECT).build(), DefaultLink.builder().providerId(PID).src(of2p2).dst(of4p1).type(DIRECT).build());
Set<FilteredConnectPoint> ingress = ImmutableSet.of(new FilteredConnectPoint(of3p1, vlan100Selector), new FilteredConnectPoint(of1p1, vlan100Selector));
Set<FilteredConnectPoint> egress = ImmutableSet.of(new FilteredConnectPoint(of4p2, vlan100Selector));
EncapsulationConstraint constraint = new EncapsulationConstraint(EncapsulationType.VLAN);
LinkCollectionIntent intent = LinkCollectionIntent.builder().appId(appId).selector(ethDstSelector).treatment(treatment).links(testLinks).filteredIngressPoints(ingress).filteredEgressPoints(egress).constraints(ImmutableList.of(constraint)).build();
List<Intent> result = compiler.compile(intent, Collections.emptyList());
assertThat(result, hasSize(1));
assertThat(result.get(0), instanceOf(FlowObjectiveIntent.class));
FlowObjectiveIntent foIntent = (FlowObjectiveIntent) result.get(0);
List<Objective> objectives = foIntent.objectives();
assertThat(objectives, hasSize(15));
TrafficSelector expectSelector = DefaultTrafficSelector.builder(ethDstSelector).matchInPort(PortNumber.portNumber(1)).matchVlanId(VLAN_100).build();
TrafficSelector filteringSelector = vlan100Selector;
TrafficTreatment expectTreatment = DefaultTrafficTreatment.builder().setVlanId(VLAN_1).setOutput(PortNumber.portNumber(2)).build();
/*
* First set of objective
*/
filteringObjective = (FilteringObjective) objectives.get(0);
forwardingObjective = (ForwardingObjective) objectives.get(1);
nextObjective = (NextObjective) objectives.get(2);
PortCriterion inPortCriterion = (PortCriterion) expectSelector.getCriterion(Criterion.Type.IN_PORT);
// test case for first filtering objective
checkFiltering(filteringObjective, inPortCriterion, intent.priority(), null, appId, true, filteringSelector.criteria());
// test case for first next objective
checkNext(nextObjective, SIMPLE, expectTreatment, expectSelector, ADD);
// test case for first forwarding objective
checkForward(forwardingObjective, ADD, expectSelector, nextObjective.id(), SPECIFIC);
/*
* Second set of objective
*/
filteringObjective = (FilteringObjective) objectives.get(3);
forwardingObjective = (ForwardingObjective) objectives.get(4);
nextObjective = (NextObjective) objectives.get(5);
expectSelector = DefaultTrafficSelector.builder().matchInPort(PortNumber.portNumber(1)).matchVlanId(VLAN_1).build();
filteringSelector = vlan1Selector;
expectTreatment = DefaultTrafficTreatment.builder().setVlanId(VLAN_100).setOutput(PortNumber.portNumber(2)).build();
// test case for second filtering objective
checkFiltering(filteringObjective, inPortCriterion, intent.priority(), null, appId, true, filteringSelector.criteria());
// test case for second next objective
checkNext(nextObjective, SIMPLE, expectTreatment, expectSelector, ADD);
// test case for second forwarding objective
checkForward(forwardingObjective, ADD, expectSelector, nextObjective.id(), SPECIFIC);
/*
* 3rd set of objective
*/
filteringObjective = (FilteringObjective) objectives.get(6);
forwardingObjective = (ForwardingObjective) objectives.get(7);
nextObjective = (NextObjective) objectives.get(8);
filteringSelector = vlan100Selector;
expectTreatment = DefaultTrafficTreatment.builder().setVlanId(VLAN_1).setOutput(PortNumber.portNumber(2)).build();
expectSelector = DefaultTrafficSelector.builder(ethDstSelector).matchInPort(PortNumber.portNumber(1)).matchVlanId(VLAN_100).build();
// test case for 3rd filtering objective
checkFiltering(filteringObjective, inPortCriterion, intent.priority(), null, appId, true, filteringSelector.criteria());
// test case for 3rd next objective
checkNext(nextObjective, SIMPLE, expectTreatment, expectSelector, ADD);
// test case for 3rd forwarding objective
checkForward(forwardingObjective, ADD, expectSelector, nextObjective.id(), SPECIFIC);
/*
* 4th set of objective
*/
filteringObjective = (FilteringObjective) objectives.get(9);
forwardingObjective = (ForwardingObjective) objectives.get(10);
nextObjective = (NextObjective) objectives.get(11);
filteringSelector = vlan1Selector;
expectSelector = DefaultTrafficSelector.builder().matchInPort(PortNumber.portNumber(1)).matchVlanId(VLAN_1).build();
// test case for 4th filtering objective
checkFiltering(filteringObjective, inPortCriterion, intent.priority(), null, appId, true, filteringSelector.criteria());
// test case for 4th next objective
checkNext(nextObjective, SIMPLE, expectTreatment, expectSelector, ADD);
// test case for 4th forwarding objective
checkForward(forwardingObjective, ADD, expectSelector, nextObjective.id(), SPECIFIC);
/*
* 5th set of objective
*/
filteringObjective = (FilteringObjective) objectives.get(12);
forwardingObjective = (ForwardingObjective) objectives.get(13);
nextObjective = (NextObjective) objectives.get(14);
expectSelector = DefaultTrafficSelector.builder().matchVlanId(VlanId.vlanId("1")).matchInPort(PortNumber.portNumber(3)).build();
inPortCriterion = (PortCriterion) expectSelector.getCriterion(Criterion.Type.IN_PORT);
// test case for 5th filtering objective
checkFiltering(filteringObjective, inPortCriterion, intent.priority(), null, appId, true, filteringSelector.criteria());
// test case for 5th next objective
checkNext(nextObjective, SIMPLE, expectTreatment, expectSelector, ADD);
// test case for 5th forwarding objective
checkForward(forwardingObjective, ADD, expectSelector, nextObjective.id(), SPECIFIC);
}
use of org.onosproject.net.flowobjective.NextObjective in project onos by opennetworkinglab.
the class FlowObjectiveIntentInstallerTest method createAnotherFlowObjectiveIntents.
/**
* Creates flow objective Intents with different selector.
*
* @return the flow objective Intents
*/
private List<Intent> createAnotherFlowObjectiveIntents() {
TrafficSelector selector = DefaultTrafficSelector.builder().matchVlanId(VlanId.vlanId("100")).matchInPort(CP1.port()).build();
TrafficTreatment treatment = DefaultTrafficTreatment.builder().setOutput(CP2.port()).build();
FilteringObjective filt = DefaultFilteringObjective.builder().addCondition(selector.getCriterion(Criterion.Type.IN_PORT)).addCondition(selector.getCriterion(Criterion.Type.VLAN_VID)).withPriority(DEFAULT_PRIORITY).fromApp(APP_ID).permit().add();
NextObjective next = DefaultNextObjective.builder().withMeta(selector).addTreatment(treatment).makePermanent().withPriority(DEFAULT_PRIORITY).fromApp(APP_ID).withType(NextObjective.Type.SIMPLE).withId(NEXT_ID_1).add();
ForwardingObjective fwd = DefaultForwardingObjective.builder().withSelector(selector).fromApp(APP_ID).withPriority(DEFAULT_PRIORITY).makePermanent().withFlag(ForwardingObjective.Flag.SPECIFIC).nextStep(NEXT_ID_1).add();
List<Objective> objectives = ImmutableList.of(filt, next, fwd);
List<DeviceId> deviceIds = ImmutableList.of(CP1.deviceId(), CP1.deviceId(), CP1.deviceId());
List<NetworkResource> resources = ImmutableList.of(CP1.deviceId());
Intent intent = new FlowObjectiveIntent(APP_ID, KEY1, deviceIds, objectives, resources, RG1);
return ImmutableList.of(intent);
}
use of org.onosproject.net.flowobjective.NextObjective in project onos by opennetworkinglab.
the class Ofdpa2GroupHandler method prepareL2UnfilteredGroup.
private List<GroupInfo> prepareL2UnfilteredGroup(NextObjective nextObj) {
ImmutableList.Builder<GroupInfo> groupInfoBuilder = ImmutableList.builder();
// break up broadcast next objective to multiple groups
Collection<TrafficTreatment> treatments = nextObj.nextTreatments().stream().filter(nt -> nt.type() == NextTreatment.Type.TREATMENT).map(nt -> ((DefaultNextTreatment) nt).treatment()).collect(Collectors.toSet());
Collection<Integer> nextIds = nextObj.nextTreatments().stream().filter(nt -> nt.type() == NextTreatment.Type.ID).map(nt -> ((IdNextTreatment) nt).nextId()).collect(Collectors.toSet());
// Each treatment is converted to an L2 unfiltered group
treatments.forEach(treatment -> {
TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
// Extract port information
PortNumber port = treatment.allInstructions().stream().map(instr -> (Instructions.OutputInstruction) instr).map(instr -> instr.port()).findFirst().orElse(null);
if (port == null) {
log.debug("Skip bucket without output instruction");
return;
}
tBuilder.setOutput(port);
if (requireAllowVlanTransition()) {
tBuilder.extension(new OfdpaSetAllowVlanTranslation(Ofdpa3AllowVlanTranslationType.ALLOW), deviceId);
}
// Build L2UG
int l2ugk = l2UnfilteredGroupKey(deviceId, port.toLong());
final GroupKey l2UnfilterGroupKey = new DefaultGroupKey(appKryo.serialize(l2ugk));
int l2UnfilteredGroupId = L2_UNFILTERED_TYPE | ((int) port.toLong() & FOUR_NIBBLE_MASK);
GroupBucket l2UnfilteredGroupBucket = DefaultGroupBucket.createIndirectGroupBucket(tBuilder.build());
GroupDescription l2UnfilteredGroupDesc = new DefaultGroupDescription(deviceId, GroupDescription.Type.INDIRECT, new GroupBuckets(Collections.singletonList(l2UnfilteredGroupBucket)), l2UnfilterGroupKey, l2UnfilteredGroupId, nextObj.appId());
log.debug("Trying L2-Unfiltered: device:{} gid:{} gkey:{} nextid:{}", deviceId, Integer.toHexString(l2UnfilteredGroupId), l2UnfilterGroupKey, nextObj.id());
groupInfoBuilder.add(new GroupInfo(l2UnfilteredGroupDesc, l2UnfilteredGroupDesc));
});
// Save the current count
int counts = groupInfoBuilder.build().size();
// Lookup each nextId in the store and obtain the group information
nextIds.forEach(nextId -> {
NextGroup nextGroup = flowObjectiveStore.getNextGroup(nextId);
if (nextGroup != null) {
List<Deque<GroupKey>> allActiveKeys = appKryo.deserialize(nextGroup.data());
GroupKey topGroupKey = allActiveKeys.get(0).getFirst();
GroupDescription groupDesc = groupService.getGroup(deviceId, topGroupKey);
if (groupDesc != null) {
log.debug("Trying L2-Hash device:{} gid:{}, gkey:{}, nextid:{}", deviceId, Integer.toHexString(((Group) groupDesc).id().id()), topGroupKey, nextId);
groupInfoBuilder.add(new GroupInfo(groupDesc, groupDesc));
} else {
log.error("Not found L2-Hash device:{}, gkey:{}, nextid:{}", deviceId, topGroupKey, nextId);
}
} else {
log.error("Not found NextGroup device:{}, nextid:{}", deviceId, nextId);
}
});
// Compare the size before and after to detect problems during the creation
ImmutableList<GroupInfo> groupInfos = groupInfoBuilder.build();
return (counts + nextIds.size()) == groupInfos.size() ? groupInfos : ImmutableList.of();
}
use of org.onosproject.net.flowobjective.NextObjective in project onos by opennetworkinglab.
the class Ofdpa2GroupHandler method addBucketToGroup.
// ////////////////////////////////////
// Group Editing
// ////////////////////////////////////
/**
* Adds a bucket to the top level group of a group-chain, and creates the chain.
* Ensures that bucket being added is not a duplicate, by checking existing
* buckets for the same output port.
*
* @param nextObjective the bucket information for a next group
* @param next the representation of the existing group-chain for this next objective
*/
protected void addBucketToGroup(NextObjective nextObjective, NextGroup next) {
if (nextObjective.type() != NextObjective.Type.HASHED && nextObjective.type() != NextObjective.Type.BROADCAST) {
log.warn("AddBuckets not applied to nextType:{} in dev:{} for next:{}", nextObjective.type(), deviceId, nextObjective.id());
fail(nextObjective, ObjectiveError.UNSUPPORTED);
return;
}
// first check to see if bucket being added is not a duplicate of an
// existing bucket. If it is for an existing output port, then its a
// duplicate.
Set<TrafficTreatment> duplicateBuckets = Sets.newHashSet();
List<Deque<GroupKey>> allActiveKeys = appKryo.deserialize(next.data());
Set<PortNumber> existingPorts = getExistingOutputPorts(allActiveKeys, groupService, deviceId);
Set<TrafficTreatment> nonDuplicateBuckets = Sets.newHashSet();
NextObjective objectiveToAdd;
nextObjective.next().forEach(trafficTreatment -> {
PortNumber portNumber = readOutPortFromTreatment(trafficTreatment);
if (portNumber == null) {
return;
}
if (existingPorts.contains(portNumber)) {
// its possible that portnumbers are same but labels are different
int label = readLabelFromTreatment(trafficTreatment);
if (label == -1) {
duplicateBuckets.add(trafficTreatment);
} else {
List<Integer> existing = existingPortAndLabel(allActiveKeys, groupService, deviceId, portNumber, label);
if (!existing.isEmpty()) {
duplicateBuckets.add(trafficTreatment);
} else {
nonDuplicateBuckets.add(trafficTreatment);
}
}
} else {
nonDuplicateBuckets.add(trafficTreatment);
}
});
if (duplicateBuckets.isEmpty()) {
// use the original objective
objectiveToAdd = nextObjective;
} else if (!nonDuplicateBuckets.isEmpty()) {
// only use the non-duplicate buckets if there are any
log.debug("Some buckets {} already exist in next id {}, duplicate " + "buckets will be ignored.", duplicateBuckets, nextObjective.id());
// new next objective with non duplicate treatments
NextObjective.Builder builder = DefaultNextObjective.builder().withType(nextObjective.type()).withId(nextObjective.id()).withMeta(nextObjective.meta()).fromApp(nextObjective.appId());
nonDuplicateBuckets.forEach(builder::addTreatment);
ObjectiveContext context = nextObjective.context().orElse(null);
objectiveToAdd = builder.addToExisting(context);
} else {
// buckets to add are already there - nothing to do
log.debug("buckets already exist {} in next: {} ..ignoring bucket add", duplicateBuckets, nextObjective.id());
pass(nextObjective);
return;
}
if (nextObjective.type() == NextObjective.Type.HASHED) {
if (isL2Hash(nextObjective)) {
addBucketToL2HashGroup(objectiveToAdd, allActiveKeys);
return;
}
addBucketToEcmpHashGroup(objectiveToAdd, allActiveKeys);
} else if (nextObjective.type() == NextObjective.Type.BROADCAST) {
addBucketToBroadcastGroup(objectiveToAdd, allActiveKeys);
}
}
use of org.onosproject.net.flowobjective.NextObjective in project onos by opennetworkinglab.
the class DefaultSingleTablePipeline method forward.
@Override
public void forward(ForwardingObjective fwd) {
TrafficSelector selector = fwd.selector();
if (fwd.treatment() != null) {
// Deal with SPECIFIC and VERSATILE in the same manner.
FlowRule.Builder ruleBuilder = DefaultFlowRule.builder().forDevice(deviceId).withSelector(selector).fromApp(fwd.appId()).withPriority(fwd.priority()).withTreatment(fwd.treatment());
if (fwd.permanent()) {
ruleBuilder.makePermanent();
} else {
ruleBuilder.makeTemporary(fwd.timeout());
}
installObjective(ruleBuilder, fwd);
} else {
NextObjective nextObjective;
NextGroup next;
TrafficTreatment treatment;
if (fwd.op() == ADD) {
// Give a try to the cache. Doing an operation
// on the store seems to be very expensive.
nextObjective = pendingAddNext.getIfPresent(fwd.nextId());
// We will try with the store
if (nextObjective == null) {
next = flowObjectiveStore.getNextGroup(fwd.nextId());
// the treatment in order to re-build the flow rule.
if (next == null) {
fwd.context().ifPresent(c -> c.onError(fwd, ObjectiveError.GROUPMISSING));
return;
}
treatment = appKryo.deserialize(next.data());
} else {
pendingAddNext.invalidate(fwd.nextId());
treatment = getTreatment(nextObjective);
if (treatment == null) {
fwd.context().ifPresent(c -> c.onError(fwd, ObjectiveError.UNSUPPORTED));
return;
}
}
} else {
// We get the NextGroup from the remove operation.
// Doing an operation on the store seems to be very expensive.
next = flowObjectiveStore.getNextGroup(fwd.nextId());
treatment = (next != null) ? appKryo.deserialize(next.data()) : null;
}
// If the treatment is null we cannot re-build the original flow
if (treatment == null) {
fwd.context().ifPresent(c -> c.onError(fwd, ObjectiveError.GROUPMISSING));
return;
}
// Finally we build the flow rule and push to the flow rule subsystem.
FlowRule.Builder ruleBuilder = DefaultFlowRule.builder().forDevice(deviceId).withSelector(selector).fromApp(fwd.appId()).withPriority(fwd.priority()).withTreatment(treatment);
if (fwd.permanent()) {
ruleBuilder.makePermanent();
} else {
ruleBuilder.makeTemporary(fwd.timeout());
}
installObjective(ruleBuilder, fwd);
}
}
Aggregations