use of org.onosproject.net.behaviour.NextGroup in project onos by opennetworkinglab.
the class AbstractHPPipeline method forward.
@Override
public void forward(ForwardingObjective fwd) {
if (fwd.treatment() != null) {
/* If UNSUPPORTED features included in ForwardingObjective a warning message is generated.
* FlowRule is anyway sent to the device, device will reply with an OFP_ERROR.
* Moreover, checkUnSupportedFeatures function generates further warnings specifying
* each unsupported feature.
*/
if (checkUnSupportedFeatures(fwd.selector(), fwd.treatment())) {
log.warn("HP Driver - specified ForwardingObjective contains UNSUPPORTED FEATURES");
}
// Deal with SPECIFIC and VERSATILE in the same manner.
// Create the FlowRule starting from the ForwardingObjective
FlowRule.Builder ruleBuilder = DefaultFlowRule.builder().forDevice(deviceId).withSelector(fwd.selector()).withTreatment(fwd.treatment()).withPriority(fwd.priority()).fromApp(fwd.appId());
// Determine the table to be used depends on selector, treatment and specific switch hardware
ruleBuilder.forTable(tableIdForForwardingObjective(fwd.selector(), fwd.treatment()));
if (fwd.permanent()) {
ruleBuilder.makePermanent();
} else {
ruleBuilder.makeTemporary(fwd.timeout());
}
log.debug("HP Driver - installing ForwadingObjective arrived with treatment {}", fwd);
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 flowrule subsystem.
FlowRule.Builder ruleBuilder = DefaultFlowRule.builder().forDevice(deviceId).withSelector(fwd.selector()).fromApp(fwd.appId()).withPriority(fwd.priority()).withTreatment(treatment);
/* If UNSUPPORTED features included in ForwardingObjective a warning message is generated.
* FlowRule is anyway sent to the device, device will reply with an OFP_ERROR.
* Moreover, checkUnSupportedFeatures function generates further warnings specifying
* each unsupported feature.
*/
if (checkUnSupportedFeatures(fwd.selector(), treatment)) {
log.warn("HP Driver - specified ForwardingObjective contains UNSUPPORTED FEATURES");
}
// Table to be used depends on the specific switch hardware and ForwardingObjective
ruleBuilder.forTable(tableIdForForwardingObjective(fwd.selector(), treatment));
if (fwd.permanent()) {
ruleBuilder.makePermanent();
} else {
ruleBuilder.makeTemporary(fwd.timeout());
}
log.debug("HP Driver - installing ForwadingObjective arrived with NULL treatment (intent)");
installObjective(ruleBuilder, fwd);
}
}
use of org.onosproject.net.behaviour.NextGroup in project onos by opennetworkinglab.
the class FlowObjectiveManager method getNextMappingsChain.
@Override
public Map<Pair<Integer, DeviceId>, List<String>> getNextMappingsChain() {
Map<Pair<Integer, DeviceId>, List<String>> nextObjGroupMap = new HashMap<>();
Map<Integer, NextGroup> allnexts = flowObjectiveStore.getAllGroups();
for (Map.Entry<Integer, NextGroup> e : allnexts.entrySet()) {
// get the device this next Objective was sent to
DeviceId deviceId = nextToDevice.get(e.getKey());
if (deviceId != null) {
// this instance of the controller sent the nextObj to a driver
Pipeliner pipeliner = getDevicePipeliner(deviceId);
List<String> nextMappings = pipeliner.getNextMappings(e.getValue());
if (nextMappings != null) {
// mappings.addAll(nextMappings);
nextObjGroupMap.put(Pair.of(e.getKey(), deviceId), nextMappings);
}
} else {
nextObjGroupMap.put(Pair.of(e.getKey(), deviceId), ImmutableList.of("nextId not in this onos instance"));
}
}
return nextObjGroupMap;
}
use of org.onosproject.net.behaviour.NextGroup in project onos by opennetworkinglab.
the class FlowObjectiveManager method getNextMappings.
@Override
public List<String> getNextMappings() {
List<String> mappings = new ArrayList<>();
Map<Integer, NextGroup> allnexts = flowObjectiveStore.getAllGroups();
for (Map.Entry<Integer, NextGroup> e : allnexts.entrySet()) {
// get the device this next Objective was sent to
DeviceId deviceId = nextToDevice.get(e.getKey());
mappings.add("NextId " + e.getKey() + ": " + ((deviceId != null) ? deviceId : "nextId not in this onos instance"));
if (deviceId != null) {
// this instance of the controller sent the nextObj to a driver
Pipeliner pipeliner = getDevicePipeliner(deviceId);
List<String> nextMappings = pipeliner.getNextMappings(e.getValue());
if (nextMappings != null) {
mappings.addAll(nextMappings);
}
}
}
return mappings;
}
use of org.onosproject.net.behaviour.NextGroup 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.behaviour.NextGroup in project onos by opennetworkinglab.
the class Ofdpa2GroupHandler method addBucketToL3MulticastGroup.
private void addBucketToL3MulticastGroup(NextObjective nextObj, List<Deque<GroupKey>> allActiveKeys, List<GroupInfo> groupInfos, VlanId assignedVlan) {
// Create the buckets to add to the outermost L3 Multicast group
List<GroupBucket> newBuckets = createL3MulticastBucket(groupInfos);
// get the group being edited
Group l3mcastGroup = retrieveTopLevelGroup(allActiveKeys, deviceId, groupService, nextObj.id());
if (l3mcastGroup == null) {
fail(nextObj, ObjectiveError.GROUPMISSING);
return;
}
GroupKey l3mcastGroupKey = l3mcastGroup.appCookie();
int l3mcastGroupId = l3mcastGroup.id().id();
// ensure assignedVlan applies to the chosen group
VlanId expectedVlan = extractVlanIdFromGroupId(l3mcastGroupId);
if (!expectedVlan.equals(assignedVlan)) {
log.warn("VLAN ID {} does not match L3 Mcast group {} to which bucket is " + "being added, for next:{} in dev:{}. Abort.", assignedVlan, Integer.toHexString(l3mcastGroupId), nextObj.id(), deviceId);
fail(nextObj, ObjectiveError.BADPARAMS);
}
GroupDescription l3mcastGroupDescription = new DefaultGroupDescription(deviceId, ALL, new GroupBuckets(newBuckets), l3mcastGroupKey, l3mcastGroupId, nextObj.appId());
GroupChainElem l3mcastGce = new GroupChainElem(l3mcastGroupDescription, groupInfos.size(), true, deviceId);
List<Deque<GroupKey>> addedKeys = new ArrayList<>();
groupInfos.forEach(groupInfo -> {
// update original NextGroup with new bucket-chain
Deque<GroupKey> newBucketChain = new ArrayDeque<>();
newBucketChain.addFirst(groupInfo.innerMostGroupDesc().appCookie());
// Add L3 interface group to the chain if there is one.
if (!groupInfo.nextGroupDesc().equals(groupInfo.innerMostGroupDesc())) {
newBucketChain.addFirst(groupInfo.nextGroupDesc().appCookie());
}
newBucketChain.addFirst(l3mcastGroupKey);
addedKeys.add(newBucketChain);
updatePendingGroups(groupInfo.nextGroupDesc().appCookie(), l3mcastGce);
// Point next group to inner-most group, if any
if (!groupInfo.nextGroupDesc().equals(groupInfo.innerMostGroupDesc())) {
GroupChainElem innerGce = new GroupChainElem(groupInfo.nextGroupDesc(), 1, false, deviceId);
updatePendingGroups(groupInfo.innerMostGroupDesc().appCookie(), innerGce);
}
log.debug("Adding to L3MCAST: device:{} gid:{} group key:{} nextId:{}", deviceId, Integer.toHexString(l3mcastGroupId), l3mcastGroupKey, nextObj.id());
// send the innermost group
log.debug("Sending innermost group {} in group chain on device {} ", Integer.toHexString(groupInfo.innerMostGroupDesc().givenGroupId()), deviceId);
groupService.addGroup(groupInfo.innerMostGroupDesc());
});
updatePendingNextObjective(l3mcastGroupKey, new OfdpaNextGroup(addedKeys, nextObj));
}
Aggregations