use of org.onosproject.net.group.GroupBucket in project onos by opennetworkinglab.
the class Ofdpa2GroupHandler method removeBucket.
/**
* Removes top-level buckets from a group that represents the given next objective.
*
* @param chainsToRemove a list of group bucket chains to remove
* @param nextObjective the next objective that contains information for the
* buckets to be removed from the group
*/
protected void removeBucket(List<Deque<GroupKey>> chainsToRemove, NextObjective nextObjective) {
List<GroupBucket> bucketsToRemove = Lists.newArrayList();
// first group key is the one we want to modify
GroupKey modGroupKey = chainsToRemove.get(0).peekFirst();
Group modGroup = groupService.getGroup(deviceId, modGroupKey);
if (modGroup == null) {
log.warn("removeBucket(): Attempt to modify non-existent group {} for device {}", modGroupKey, deviceId);
return;
}
for (Deque<GroupKey> foundChain : chainsToRemove) {
// second group key is the one we wish to remove the reference to
if (foundChain.size() < 2) {
// additional check to make sure second group key exists in
// the chain.
log.warn("Can't find second group key from chain {}", foundChain);
continue;
}
GroupKey pointedGroupKey = foundChain.stream().collect(Collectors.toList()).get(1);
Group pointedGroup = groupService.getGroup(deviceId, pointedGroupKey);
if (pointedGroup == null) {
continue;
}
GroupBucket bucket;
if (nextObjective.type() == NextObjective.Type.HASHED) {
bucket = DefaultGroupBucket.createSelectGroupBucket(DefaultTrafficTreatment.builder().group(pointedGroup.id()).build());
} else {
bucket = DefaultGroupBucket.createAllGroupBucket(DefaultTrafficTreatment.builder().group(pointedGroup.id()).build());
}
bucketsToRemove.add(bucket);
}
GroupBuckets removeBuckets = new GroupBuckets(bucketsToRemove);
// for debug log
List<String> pointedGroupIds;
pointedGroupIds = bucketsToRemove.stream().map(GroupBucket::treatment).map(TrafficTreatment::allInstructions).flatMap(List::stream).filter(inst -> inst instanceof Instructions.GroupInstruction).map(inst -> (Instructions.GroupInstruction) inst).map(Instructions.GroupInstruction::groupId).map(GroupId::id).map(Integer::toHexString).map(id -> HEX_PREFIX + id).collect(Collectors.toList());
log.debug("Removing buckets from group id 0x{} pointing to group id(s) {} " + "for next id {} in device {}", Integer.toHexString(modGroup.id().id()), pointedGroupIds, nextObjective.id(), deviceId);
addPendingUpdateNextObjective(modGroupKey, nextObjective);
groupService.removeBucketsFromGroup(deviceId, modGroupKey, removeBuckets, modGroupKey, nextObjective.appId());
// potentially stale copy of allActiveKeys
synchronized (flowObjectiveStore) {
// get a fresh copy of what the store holds
NextGroup next = flowObjectiveStore.getNextGroup(nextObjective.id());
List<Deque<GroupKey>> allActiveKeys = appKryo.deserialize(next.data());
allActiveKeys = Lists.newArrayList(allActiveKeys);
// Note that since we got a new object, and ArrayDeque does not implement
// Object.equals(), we have to check the deque elems one by one
allActiveKeys.removeIf(active -> chainsToRemove.stream().anyMatch(remove -> Arrays.equals(remove.toArray(new GroupKey[0]), active.toArray(new GroupKey[0]))));
// top level group which still exists.
if (allActiveKeys.isEmpty()) {
ArrayDeque<GroupKey> top = new ArrayDeque<>();
top.add(modGroupKey);
allActiveKeys.add(top);
}
flowObjectiveStore.putNextGroup(nextObjective.id(), new OfdpaNextGroup(allActiveKeys, nextObjective));
}
}
use of org.onosproject.net.group.GroupBucket in project onos by opennetworkinglab.
the class Ofdpa2GroupHandler method addBucketToEcmpHashGroup.
private void addBucketToEcmpHashGroup(NextObjective nextObjective, List<Deque<GroupKey>> allActiveKeys) {
// storage for all group keys in the chain of groups created
List<Deque<GroupKey>> allGroupKeys = new ArrayList<>();
List<GroupInfo> unsentGroups = new ArrayList<>();
List<GroupBucket> newBuckets;
createEcmpHashBucketChains(nextObjective, allGroupKeys, unsentGroups);
// now we can create the buckets to add to the outermost L3 ECMP group
newBuckets = generateNextGroupBuckets(unsentGroups, SELECT);
// retrieve the original L3 ECMP group
Group l3ecmpGroup = retrieveTopLevelGroup(allActiveKeys, deviceId, groupService, nextObjective.id());
if (l3ecmpGroup == null) {
fail(nextObjective, ObjectiveError.GROUPMISSING);
return;
}
GroupKey l3ecmpGroupKey = l3ecmpGroup.appCookie();
int l3ecmpGroupId = l3ecmpGroup.id().id();
// Although GroupDescriptions are not necessary for adding buckets to
// existing groups, we still use one in the GroupChainElem. When the latter is
// processed, the info will be extracted for the bucketAdd call to groupService
GroupDescription l3ecmpGroupDesc = new DefaultGroupDescription(deviceId, SELECT, new GroupBuckets(newBuckets), l3ecmpGroupKey, l3ecmpGroupId, nextObjective.appId());
GroupChainElem l3ecmpGce = new GroupChainElem(l3ecmpGroupDesc, unsentGroups.size(), true, deviceId);
// update new bucket-chains
List<Deque<GroupKey>> addedKeys = new ArrayList<>();
for (Deque<GroupKey> newBucketChain : allGroupKeys) {
newBucketChain.addFirst(l3ecmpGroupKey);
addedKeys.add(newBucketChain);
}
updatePendingNextObjective(l3ecmpGroupKey, new OfdpaNextGroup(addedKeys, nextObjective));
log.debug("Adding to L3ECMP: device:{} gid:{} group key:{} nextId:{}", deviceId, Integer.toHexString(l3ecmpGroupId), l3ecmpGroupKey, nextObjective.id());
unsentGroups.forEach(groupInfo -> {
// send the innermost group
log.debug("Sending innermost group {} in group chain on device {} ", Integer.toHexString(groupInfo.innerMostGroupDesc().givenGroupId()), deviceId);
updatePendingGroups(groupInfo.nextGroupDesc().appCookie(), l3ecmpGce);
groupService.addGroup(groupInfo.innerMostGroupDesc());
});
}
use of org.onosproject.net.group.GroupBucket in project onos by opennetworkinglab.
the class Ofdpa2GroupHandler method processEcmpHashedNextObjective.
/**
* As per the OFDPA 2.0 TTP, packets are sent out of ports by using
* a chain of groups. The hashed Next Objective passed in by the application
* has to be broken up into a group chain comprising of an
* L3 ECMP group as the top level group. Buckets of this group can point
* to a variety of groups in a group chain, depending on the whether
* MPLS labels are being pushed or not.
* <p>
* NOTE: We do not create MPLS ECMP groups as they are unimplemented in
* OF-DPA 2.0 (even though it is in the spec). Therefore we do not
* check the nextObjective meta to see what is matching before being
* sent to this nextObjective.
*
* @param nextObj the nextObjective of type HASHED
*/
protected void processEcmpHashedNextObjective(NextObjective nextObj) {
// storage for all group keys in the chain of groups created
List<Deque<GroupKey>> allGroupKeys = new ArrayList<>();
List<GroupInfo> unsentGroups = new ArrayList<>();
createEcmpHashBucketChains(nextObj, allGroupKeys, unsentGroups);
// now we can create the outermost L3 ECMP group
List<GroupBucket> l3ecmpGroupBuckets = new ArrayList<>();
for (GroupInfo gi : unsentGroups) {
// create ECMP bucket to point to the outer group
TrafficTreatment.Builder ttb = DefaultTrafficTreatment.builder();
ttb.group(new GroupId(gi.nextGroupDesc().givenGroupId()));
GroupBucket sbucket = DefaultGroupBucket.createSelectGroupBucket(ttb.build());
l3ecmpGroupBuckets.add(sbucket);
}
int l3ecmpIndex = getNextAvailableIndex();
int l3ecmpGroupId = L3_ECMP_TYPE | (TYPE_MASK & l3ecmpIndex);
GroupKey l3ecmpGroupKey = new DefaultGroupKey(appKryo.serialize(l3ecmpIndex));
GroupDescription l3ecmpGroupDesc = new DefaultGroupDescription(deviceId, SELECT, new GroupBuckets(l3ecmpGroupBuckets), l3ecmpGroupKey, l3ecmpGroupId, nextObj.appId());
GroupChainElem l3ecmpGce = new GroupChainElem(l3ecmpGroupDesc, l3ecmpGroupBuckets.size(), false, deviceId);
// create objects for local and distributed storage
allGroupKeys.forEach(gKeyChain -> gKeyChain.addFirst(l3ecmpGroupKey));
OfdpaNextGroup ofdpaGrp = new OfdpaNextGroup(allGroupKeys, nextObj);
// store l3ecmpGroupKey with the ofdpaGroupChain for the nextObjective
// that depends on it
updatePendingNextObjective(l3ecmpGroupKey, ofdpaGrp);
log.debug("Trying L3ECMP: device:{} gid:{} gkey:{} nextId:{}", deviceId, Integer.toHexString(l3ecmpGroupId), l3ecmpGroupKey, nextObj.id());
// finally we are ready to send the innermost groups
for (GroupInfo gi : unsentGroups) {
log.debug("Sending innermost group {} in group chain on device {} ", Integer.toHexString(gi.innerMostGroupDesc().givenGroupId()), deviceId);
updatePendingGroups(gi.nextGroupDesc().appCookie(), l3ecmpGce);
groupService.addGroup(gi.innerMostGroupDesc());
}
}
use of org.onosproject.net.group.GroupBucket in project onos by opennetworkinglab.
the class Ofdpa3GroupHandler method createMplsL2VpnGroup.
/**
* Helper method to create a mpls l2 vpn group.
*
* @param nextGroupId the next group in the chain
* @param index the index of the group
* @param instructions the instructions to push
* @param applicationId the application id
* @return the group description
*/
private GroupDescription createMplsL2VpnGroup(int nextGroupId, int index, List<Instruction> instructions, ApplicationId applicationId) {
TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
// We add the extensions and the instructions.
treatment.extension(new Ofdpa3PushL2Header(), deviceId);
treatment.pushVlan();
instructions.forEach(treatment::add);
treatment.extension(new Ofdpa3PushCw(), deviceId);
// We point the group to the next group.
treatment.group(new GroupId(nextGroupId));
GroupBucket groupBucket = DefaultGroupBucket.createIndirectGroupBucket(treatment.build());
// Finally we build the group description.
int groupId = makeMplsLabelGroupId(OfdpaMplsGroupSubType.L2_VPN, index);
GroupKey groupKey = new DefaultGroupKey(Ofdpa2Pipeline.appKryo.serialize(index));
return new DefaultGroupDescription(deviceId, INDIRECT, new GroupBuckets(Collections.singletonList(groupBucket)), groupKey, groupId, applicationId);
}
use of org.onosproject.net.group.GroupBucket in project onos by opennetworkinglab.
the class OfdpaGroupHandlerUtility method createL3MulticastBucket.
static List<GroupBucket> createL3MulticastBucket(List<GroupInfo> groupInfos) {
List<GroupBucket> l3McastBuckets = new ArrayList<>();
// For each inner group
groupInfos.forEach(groupInfo -> {
// Points to L3 interface group if there is one.
// Otherwise points to L2 interface group directly.
GroupDescription nextGroupDesc = (groupInfo.nextGroupDesc() != null) ? groupInfo.nextGroupDesc() : groupInfo.innerMostGroupDesc();
TrafficTreatment.Builder ttb = DefaultTrafficTreatment.builder();
ttb.group(new GroupId(nextGroupDesc.givenGroupId()));
GroupBucket abucket = DefaultGroupBucket.createAllGroupBucket(ttb.build());
l3McastBuckets.add(abucket);
});
// Done return the new list of buckets
return l3McastBuckets;
}
Aggregations