use of org.onosproject.net.flow.instructions.Instructions.OutputInstruction in project onos by opennetworkinglab.
the class OfdpaPipelineTraceable method handleOutputFlows.
// Handles output flows
private List<FlowEntry> handleOutputFlows(TrafficSelector currentPacket, List<FlowEntry> outputFlows, TrafficSelector.Builder egressPacket, List<PortNumber> outputPorts, PipelineTraceableHitChain currentHitChain, PipelineTraceableOutput.Builder outputBuilder, TrafficSelector initialPacket) {
// TODO optimization
// outputFlows contains also last rule of device, so we need filtering for OUTPUT instructions.
List<FlowEntry> outputFlowEntries = outputFlows.stream().filter(flow -> flow.treatment().allInstructions().stream().filter(instruction -> instruction.type().equals(Instruction.Type.OUTPUT)).count() > 0).collect(Collectors.toList());
if (outputFlowEntries.size() > 1) {
outputBuilder.appendToLog("More than one flow rule with OUTPUT instruction");
log.warn("There cannot be more than one flow entry with OUTPUT instruction for {}", currentPacket);
}
if (outputFlowEntries.size() == 1) {
OutputInstruction outputInstruction = (OutputInstruction) outputFlowEntries.get(0).treatment().allInstructions().stream().filter(instruction -> instruction.type().equals(Instruction.Type.OUTPUT)).findFirst().get();
buildOutputFromDevice(egressPacket, outputPorts, outputInstruction, currentHitChain, outputBuilder, initialPacket, false);
}
return outputFlowEntries;
}
use of org.onosproject.net.flow.instructions.Instructions.OutputInstruction in project onos by opennetworkinglab.
the class OfdpaPipelineTraceable method getGroupsFromInstructions.
// Gets group information from instructions.
private void getGroupsFromInstructions(Map<GroupId, Group> groups, List<Instruction> instructions, TrafficSelector.Builder egressPacket, List<PortNumber> outputPorts, PipelineTraceableHitChain currentHitChain, PipelineTraceableOutput.Builder outputBuilder, PipelineTraceableInput input, boolean dropped) {
List<Instruction> groupInstructionlist = new ArrayList<>();
// sort instructions according to priority (larger Instruction.Type ENUM constant first)
// which enables to treat other actions before the OUTPUT action
// TODO improve the priority scheme according to the OpenFlow ActionSet spec
List<Instruction> instructionsSorted = new ArrayList<>();
instructionsSorted.addAll(instructions);
instructionsSorted.sort((instr1, instr2) -> Integer.compare(instr2.type().ordinal(), instr1.type().ordinal()));
// Handles first all non-group instructions
for (Instruction instruction : instructionsSorted) {
log.debug("Considering Instruction {}", instruction);
// to the possible outputs for this packet
if (!instruction.type().equals(Instruction.Type.GROUP)) {
// or add the output to the possible outputs for this packet
if (instruction.type().equals(Instruction.Type.OUTPUT)) {
buildOutputFromDevice(egressPacket, outputPorts, (OutputInstruction) instruction, currentHitChain, outputBuilder, input.ingressPacket().packet(), dropped);
} else {
egressPacket = translateInstruction(egressPacket, instruction);
}
} else {
// Store for later if the instruction is pointing to a group
groupInstructionlist.add(instruction);
}
}
// handle all the internal instructions pointing to a group.
for (Instruction instr : groupInstructionlist) {
Instructions.GroupInstruction groupInstruction = (Instructions.GroupInstruction) instr;
Group group = groups.get(groupInstruction.groupId());
// group does not exist in the dataplane
if (group == null) {
currentHitChain.setEgressPacket(new PipelineTraceablePacket(egressPacket.build()));
currentHitChain.dropped();
outputBuilder.appendToLog("Null group for Instruction " + instr).noGroups().addHitChain(currentHitChain);
break;
}
log.debug("Analyzing group {}", group.id());
// group is there but there are no members/buckets
if (group.buckets().buckets().size() == 0) {
// add the group to the traversed groups
currentHitChain.addDataPlaneEntity(new DataPlaneEntity(group));
currentHitChain.setEgressPacket(new PipelineTraceablePacket(egressPacket.build()));
currentHitChain.dropped();
outputBuilder.appendToLog("Group " + group.id() + " has no buckets").noMembers().addHitChain(currentHitChain);
break;
}
PipelineTraceableHitChain newHitChain;
TrafficSelector.Builder newEgressPacket;
// Cycle in each of the group's buckets and add them to the groups for this Device.
for (GroupBucket bucket : group.buckets().buckets()) {
// add the group to the traversed groups
currentHitChain.addDataPlaneEntity(new DataPlaneEntity(group));
// Go to the next step - using a copy of the egress packet and of the hit chain
newHitChain = PipelineTraceableHitChain.emptyHitChain();
currentHitChain.hitChain().forEach(newHitChain::addDataPlaneEntity);
newEgressPacket = DefaultTrafficSelector.builder(egressPacket.build());
getGroupsFromInstructions(groups, bucket.treatment().allInstructions(), newEgressPacket, outputPorts, newHitChain, outputBuilder, input, dropped | isDropped(group.id(), bucket, input.ingressPort()));
}
}
}
use of org.onosproject.net.flow.instructions.Instructions.OutputInstruction in project onos by opennetworkinglab.
the class Ofdpa2Pipeline method getNextMappings.
@Override
public List<String> getNextMappings(NextGroup nextGroup) {
List<String> mappings = new ArrayList<>();
List<Deque<GroupKey>> gkeys = appKryo.deserialize(nextGroup.data());
for (Deque<GroupKey> gkd : gkeys) {
Group lastGroup = null;
StringBuilder gchain = new StringBuilder();
for (GroupKey gk : gkd) {
Group g = groupService.getGroup(deviceId, gk);
if (g == null) {
gchain.append(" NoGrp").append(" -->");
continue;
}
gchain.append(" 0x").append(Integer.toHexString(g.id().id())).append(" -->");
lastGroup = g;
}
// add port information for last group in group-chain
List<Instruction> lastGroupIns = new ArrayList<>();
if (lastGroup != null && !lastGroup.buckets().buckets().isEmpty()) {
lastGroupIns = lastGroup.buckets().buckets().get(0).treatment().allInstructions();
}
for (Instruction i : lastGroupIns) {
if (i instanceof OutputInstruction) {
gchain.append(" port:").append(((OutputInstruction) i).port());
}
}
mappings.add(gchain.toString());
}
return mappings;
}
use of org.onosproject.net.flow.instructions.Instructions.OutputInstruction in project fabric-tna by stratum.
the class FabricTreatmentInterpreter method mapNextHashedOrSimpleTreatment.
private static PiAction mapNextHashedOrSimpleTreatment(TrafficTreatment treatment, PiTableId tableId, boolean simple) throws PiInterpreterException {
// Provide mapping for output_hashed and routing_hashed; multicast_hashed
// can only be invoked with PiAction, hence no mapping. outPort required for
// all actions. Presence of other instructions will determine which action to map to.
final PortNumber outPort = ((OutputInstruction) instructionOrFail(treatment, OUTPUT, tableId)).port();
final ModEtherInstruction ethDst = (ModEtherInstruction) l2Instruction(treatment, ETH_DST);
final ModEtherInstruction ethSrc = (ModEtherInstruction) l2Instruction(treatment, ETH_SRC);
final PiAction.Builder actionBuilder = PiAction.builder().withParameter(new PiActionParam(P4InfoConstants.PORT_NUM, outPort.toLong()));
if (ethDst != null && ethSrc != null) {
actionBuilder.withParameter(new PiActionParam(P4InfoConstants.SMAC, ethSrc.mac().toBytes()));
actionBuilder.withParameter(new PiActionParam(P4InfoConstants.DMAC, ethDst.mac().toBytes()));
// routing_hashed
return actionBuilder.withId(P4InfoConstants.FABRIC_INGRESS_NEXT_ROUTING_HASHED).build();
} else {
// output_hashed
return actionBuilder.withId(P4InfoConstants.FABRIC_INGRESS_NEXT_OUTPUT_HASHED).build();
}
}
Aggregations