use of org.onosproject.net.flowobjective.DefaultNextTreatment in project onos by opennetworkinglab.
the class NextObjectiveTranslator method selectGroup.
private int selectGroup(NextObjective obj, ObjectiveTranslation.Builder resultBuilder) throws FabricPipelinerException {
final PiTableId hashedTableId = FabricConstants.FABRIC_INGRESS_NEXT_HASHED;
final List<DefaultNextTreatment> defaultNextTreatments = defaultNextTreatments(obj.nextTreatments(), true);
final List<TrafficTreatment> piTreatments = Lists.newArrayList();
for (DefaultNextTreatment t : defaultNextTreatments) {
// Map treatment to PI...
piTreatments.add(mapTreatmentToPiIfNeeded(t.treatment(), hashedTableId));
// ...and handle egress if necessary.
handleEgress(obj, t.treatment(), resultBuilder, false);
}
final List<GroupBucket> bucketList = piTreatments.stream().map(DefaultGroupBucket::createSelectGroupBucket).collect(Collectors.toList());
final int groupId = obj.id();
final PiGroupKey groupKey = (PiGroupKey) getGroupKey(obj);
resultBuilder.addGroup(new DefaultGroupDescription(deviceId, GroupDescription.Type.SELECT, new GroupBuckets(bucketList), groupKey, groupId, obj.appId()));
return groupId;
}
use of org.onosproject.net.flowobjective.DefaultNextTreatment in project onos by opennetworkinglab.
the class NextObjectiveTranslator method allGroup.
private int allGroup(NextObjective obj, ObjectiveTranslation.Builder resultBuilder) throws FabricPipelinerException {
final Collection<DefaultNextTreatment> defaultNextTreatments = defaultNextTreatments(obj.nextTreatments(), true);
// multicast entries is based solely on the output port.
for (DefaultNextTreatment t : defaultNextTreatments) {
handleEgress(obj, t.treatment(), resultBuilder, true);
}
// FIXME: this implementation supports only the case in which each
// switch interface is associated with only one VLAN, otherwise we would
// need to support replicating multiple times the same packet for the
// same port while setting different VLAN IDs. Hence, collect in a set.
final Set<PortNumber> outPorts = defaultNextTreatments.stream().map(DefaultNextTreatment::treatment).map(FabricUtils::outputPort).filter(Objects::nonNull).collect(Collectors.toSet());
if (outPorts.size() != defaultNextTreatments.size()) {
throw new FabricPipelinerException(format("Found BROADCAST NextObjective with %d treatments but " + "found only %d distinct OUTPUT port numbers, cannot " + "translate to ALL groups", defaultNextTreatments.size(), outPorts.size()), ObjectiveError.UNSUPPORTED);
}
final List<GroupBucket> bucketList = outPorts.stream().map(p -> DefaultTrafficTreatment.builder().setOutput(p).build()).map(DefaultGroupBucket::createAllGroupBucket).collect(Collectors.toList());
final int groupId = obj.id();
// Use DefaultGroupKey instead of PiGroupKey as we don't have any
// action profile to apply to the groups of ALL type.
final GroupKey groupKey = getGroupKey(obj);
resultBuilder.addGroup(new DefaultGroupDescription(deviceId, GroupDescription.Type.ALL, new GroupBuckets(bucketList), groupKey, groupId, obj.appId()));
return groupId;
}
use of org.onosproject.net.flowobjective.DefaultNextTreatment in project onos by opennetworkinglab.
the class NextObjectiveTranslator method simpleNext.
private void simpleNext(NextObjective obj, ObjectiveTranslation.Builder resultBuilder, boolean forceSimple) throws FabricPipelinerException {
if (capabilities.hasHashedTable()) {
// Use hashed table when possible.
hashedNext(obj, resultBuilder);
return;
}
if (obj.nextTreatments().isEmpty()) {
// Do nothing.
return;
} else if (!forceSimple && obj.nextTreatments().size() != 1) {
throw new FabricPipelinerException(format("SIMPLE NextObjective should contain only 1 treatment, found %d", obj.nextTreatments().size()), ObjectiveError.BADPARAMS);
}
final TrafficSelector selector = nextIdSelector(obj.id());
final List<DefaultNextTreatment> treatments = defaultNextTreatments(obj.nextTreatments(), true);
if (forceSimple && treatments.size() > 1) {
log.warn("Forcing SIMPLE behavior for NextObjective with {} treatments {}", treatments.size(), obj);
}
// If not forcing, we are essentially extracting the only available treatment.
final TrafficTreatment treatment = defaultNextTreatments(obj.nextTreatments(), true).get(0).treatment();
resultBuilder.addFlowRule(flowRule(obj, FabricConstants.FABRIC_INGRESS_NEXT_SIMPLE, selector, treatment));
handleEgress(obj, treatment, resultBuilder, false);
}
use of org.onosproject.net.flowobjective.DefaultNextTreatment in project onos by opennetworkinglab.
the class NextObjectiveTranslator method indirectGroup.
private int indirectGroup(NextObjective obj, ObjectiveTranslation.Builder resultBuilder) throws FabricPipelinerException {
if (isGroupModifyOp(obj)) {
throw new FabricPipelinerException("Simple next objective does not support" + "*_TO_EXISTING operations");
}
final PiTableId hashedTableId = FabricConstants.FABRIC_INGRESS_NEXT_HASHED;
final List<DefaultNextTreatment> defaultNextTreatments = defaultNextTreatments(obj.nextTreatments(), true);
if (defaultNextTreatments.size() != 1) {
throw new FabricPipelinerException("Simple next objective must have a single" + " treatment");
}
final TrafficTreatment piTreatment;
final DefaultNextTreatment defaultNextTreatment = defaultNextTreatments.get(0);
piTreatment = mapTreatmentToPiIfNeeded(defaultNextTreatment.treatment(), hashedTableId);
handleEgress(obj, defaultNextTreatment.treatment(), resultBuilder, false);
final GroupBucket groupBucket = DefaultGroupBucket.createIndirectGroupBucket(piTreatment);
final int groupId = obj.id();
final PiGroupKey groupKey = (PiGroupKey) getGroupKey(obj);
resultBuilder.addGroup(new DefaultGroupDescription(deviceId, GroupDescription.Type.INDIRECT, new GroupBuckets(Collections.singletonList(groupBucket)), groupKey, groupId, obj.appId()));
return groupId;
}
use of org.onosproject.net.flowobjective.DefaultNextTreatment in project onos by opennetworkinglab.
the class Ofdpa2GroupHandler method prepareL2InterfaceGroup.
private List<GroupInfo> prepareL2InterfaceGroup(NextObjective nextObj, VlanId assignedVlan) {
ImmutableList.Builder<GroupInfo> groupInfoBuilder = ImmutableList.builder();
// break up broadcast next objective to multiple groups
Collection<TrafficTreatment> buckets = nextObj.nextTreatments().stream().filter(nt -> nt.type() == NextTreatment.Type.TREATMENT).map(nt -> ((DefaultNextTreatment) nt).treatment()).collect(Collectors.toSet());
// Each treatment is converted to an L2 interface group
for (TrafficTreatment treatment : buckets) {
TrafficTreatment.Builder newTreatment = DefaultTrafficTreatment.builder();
PortNumber portNum = null;
VlanId egressVlan = null;
// ensure that the only allowed treatments are pop-vlan and output
for (Instruction ins : treatment.allInstructions()) {
if (ins.type() == Instruction.Type.L2MODIFICATION) {
L2ModificationInstruction l2ins = (L2ModificationInstruction) ins;
switch(l2ins.subtype()) {
case VLAN_POP:
newTreatment.add(l2ins);
break;
case VLAN_ID:
egressVlan = ((L2ModificationInstruction.ModVlanIdInstruction) l2ins).vlanId();
break;
default:
log.debug("action {} not permitted for broadcast nextObj", l2ins.subtype());
break;
}
} else if (ins.type() == Instruction.Type.OUTPUT) {
portNum = ((Instructions.OutputInstruction) ins).port();
newTreatment.add(ins);
} else {
log.debug("TrafficTreatment of type {} not permitted in " + " broadcast nextObjective", ins.type());
}
}
if (portNum == null) {
log.debug("Can't find output port for the bucket {}.", treatment);
continue;
}
// assemble info for l2 interface group
VlanId l2InterfaceGroupVlan = (egressVlan != null && !assignedVlan.equals(egressVlan)) ? egressVlan : assignedVlan;
int l2gk = l2InterfaceGroupKey(deviceId, l2InterfaceGroupVlan, portNum.toLong());
final GroupKey l2InterfaceGroupKey = new DefaultGroupKey(appKryo.serialize(l2gk));
int l2InterfaceGroupId = L2_INTERFACE_TYPE | ((l2InterfaceGroupVlan.toShort() & THREE_NIBBLE_MASK) << PORT_LEN) | ((int) portNum.toLong() & FOUR_NIBBLE_MASK);
GroupBucket l2InterfaceGroupBucket = DefaultGroupBucket.createIndirectGroupBucket(newTreatment.build());
GroupDescription l2InterfaceGroupDescription = new DefaultGroupDescription(deviceId, GroupDescription.Type.INDIRECT, new GroupBuckets(Collections.singletonList(l2InterfaceGroupBucket)), l2InterfaceGroupKey, l2InterfaceGroupId, nextObj.appId());
log.debug("Trying L2-Interface: device:{} gid:{} gkey:{} nextid:{}", deviceId, Integer.toHexString(l2InterfaceGroupId), l2InterfaceGroupKey, nextObj.id());
groupInfoBuilder.add(new GroupInfo(l2InterfaceGroupDescription, l2InterfaceGroupDescription));
}
return groupInfoBuilder.build();
}
Aggregations