use of org.onosproject.net.PipelineTraceableHitChain in project onos by opennetworkinglab.
the class OfdpaPipelineTraceableTest method testOvsOfdpaArp.
/**
* Test punt arp for ovs-ofdpa.
*/
@Test
public void testOvsOfdpaArp() {
PipelineTraceableInput pipelineInput = new PipelineTraceableInput(new PipelineTraceablePacket(IN_ARP_PACKET), OFDPA_CP, getDataPlaneEntities(OVS_OFDPA_DRIVER, ARP_OVS_OFDPA));
PipelineTraceable pipelineTraceable = setUpOvsOfdpa();
PipelineTraceableOutput pipelineOutput = pipelineTraceable.apply(pipelineInput);
assertNotNull(pipelineOutput);
assertThat(pipelineOutput.hitChains().size(), is(3));
assertThat(pipelineOutput.result(), is(PipelineTraceableResult.SUCCESS));
PipelineTraceableHitChain hitChain = pipelineOutput.hitChains().get(0);
assertNotNull(hitChain);
List<List<DataPlaneEntity>> chains = getHitChains(ARP_OVS_OFDPA);
assertThat(chains.size(), is(3));
// This is the copy sent to the controller
assertNotNull(hitChain.outputPort());
assertThat(hitChain.outputPort().port(), is(PortNumber.CONTROLLER));
assertThat(hitChain.hitChain().size(), is(7));
assertEquals(IN_ARP_PACKET, hitChain.egressPacket().packet());
assertFalse(hitChain.isDropped());
assertEquals(chains.get(0), hitChain.hitChain());
// This is the copy sent to the member port
hitChain = pipelineOutput.hitChains().get(1);
assertNotNull(hitChain);
assertNotNull(hitChain.outputPort());
assertThat(hitChain.outputPort().port(), is(OUT_PORT));
assertThat(hitChain.hitChain().size(), is(8));
assertEquals(IN_ARP_PACKET, hitChain.egressPacket().packet());
assertFalse(hitChain.isDropped());
assertEquals(chains.get(1), hitChain.hitChain());
// This is the copy sent on the input port
hitChain = pipelineOutput.hitChains().get(2);
assertNotNull(hitChain);
assertNotNull(hitChain.outputPort());
assertThat(hitChain.outputPort().port(), is(PORT));
assertThat(hitChain.hitChain().size(), is(8));
assertEquals(IN_ARP_PACKET, hitChain.egressPacket().packet());
assertTrue(hitChain.isDropped());
assertEquals(chains.get(2), hitChain.hitChain());
}
use of org.onosproject.net.PipelineTraceableHitChain in project onos by opennetworkinglab.
the class OfdpaPipelineTraceableTest method testOfdpaPuntIP.
/**
* Test punt ip for ofdpa.
*/
@Test
public void testOfdpaPuntIP() {
PipelineTraceableInput pipelineInput = new PipelineTraceableInput(new PipelineTraceablePacket(IN_PUNT_IP_PACKET), OFDPA_CP, getDataPlaneEntities(OFDPA_DRIVER, PUNT_IP_OFDPA));
PipelineTraceable pipelineTraceable = setUpOfdpa();
PipelineTraceableOutput pipelineOutput = pipelineTraceable.apply(pipelineInput);
assertNotNull(pipelineOutput);
assertThat(pipelineOutput.hitChains().size(), is(1));
assertThat(pipelineOutput.result(), is(PipelineTraceableResult.SUCCESS));
PipelineTraceableHitChain hitChain = pipelineOutput.hitChains().get(0);
assertNotNull(hitChain);
List<List<DataPlaneEntity>> chains = getHitChains(PUNT_IP_OFDPA);
assertThat(chains.size(), is(1));
assertNotNull(hitChain.outputPort());
assertThat(hitChain.outputPort().port(), is(PortNumber.CONTROLLER));
assertThat(hitChain.hitChain().size(), is(4));
assertEquals(IN_PUNT_IP_PACKET, hitChain.egressPacket().packet());
assertFalse(hitChain.isDropped());
assertEquals(chains.get(0), hitChain.hitChain());
}
use of org.onosproject.net.PipelineTraceableHitChain in project onos by opennetworkinglab.
the class OfdpaPipelineTraceableTest method testOfdpaL2BridingUntagged.
/**
* Test l2 bridging with untagged hosts for ofdpa.
*/
@Test
public void testOfdpaL2BridingUntagged() {
PipelineTraceableInput pipelineInput = new PipelineTraceableInput(new PipelineTraceablePacket(IN_L2_BRIDG_UNTAG_PACKET), OFDPA_CP, getDataPlaneEntities(OFDPA_DRIVER, L2_BRIDG_UNTAG_OFDPA));
PipelineTraceable pipelineTraceable = setUpOfdpa();
PipelineTraceableOutput pipelineOutput = pipelineTraceable.apply(pipelineInput);
assertNotNull(pipelineOutput);
assertThat(pipelineOutput.hitChains().size(), is(1));
assertThat(pipelineOutput.result(), is(PipelineTraceableResult.SUCCESS));
PipelineTraceableHitChain hitChain = pipelineOutput.hitChains().get(0);
assertNotNull(hitChain);
List<List<DataPlaneEntity>> chains = getHitChains(L2_BRIDG_UNTAG_OFDPA);
assertThat(chains.size(), is(1));
assertNotNull(hitChain.outputPort());
assertThat(hitChain.outputPort().port(), is(OUT_PORT));
assertThat(hitChain.hitChain().size(), is(4));
assertEquals(IN_L2_BRIDG_UNTAG_PACKET, hitChain.egressPacket().packet());
assertFalse(hitChain.isDropped());
assertEquals(chains.get(0), hitChain.hitChain());
}
use of org.onosproject.net.PipelineTraceableHitChain 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.PipelineTraceableHitChain 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()));
}
}
}
Aggregations