Adding drop on same output of input connect point
Change-Id: I316a3ffaa47f9d152210474055f2877823edb992
(cherry picked from commit 31a3d1e5408ff3d95fc74b3d390dd34da647aa5a)
diff --git a/src/main/java/org/onosproject/t3/impl/TroubleshootManager.java b/src/main/java/org/onosproject/t3/impl/TroubleshootManager.java
index f3edbd6..24cd251 100644
--- a/src/main/java/org/onosproject/t3/impl/TroubleshootManager.java
+++ b/src/main/java/org/onosproject/t3/impl/TroubleshootManager.java
@@ -140,6 +140,7 @@
trace.addResultMessage("No output out of device " + in.deviceId() + ". Packet is dropped");
return trace;
}
+
//If the trace has ouputs we analyze them all
for (GroupsInDevice outputPath : trace.getGroupOuputs(in.deviceId())) {
log.debug("Output path {}", outputPath.getOutput());
@@ -382,7 +383,7 @@
for (FlowEntry entry : flows) {
getGroupsFromInstructions(trace, groups, entry.treatment().allInstructions(),
- entry.deviceId(), builder, outputPorts);
+ entry.deviceId(), builder, outputPorts, in);
}
packet = builder.build();
log.debug("Groups hit by packet {}", packet);
@@ -412,15 +413,11 @@
TrafficSelector.Builder builder, List<PortNumber> outputPorts,
Set<Instruction> outputFlowEntries) {
if (outputFlowEntries.size() > 1) {
- log.warn("There cannot be more than one OUTPUT instruction for {}", packet);
+ log.warn("There cannot be more than one flow entry with OUTPUT instruction for {}", packet);
} else {
OutputInstruction outputInstruction = (OutputInstruction) outputFlowEntries.iterator().next();
//FIXME using GroupsInDevice for output even if flows.
- trace.addGroupOutputPath(in.deviceId(),
- new GroupsInDevice(ConnectPoint.deviceConnectPoint(in.deviceId()
- + "/" + outputInstruction.port()),
- ImmutableList.of(), builder.build()));
- outputPorts.add(outputInstruction.port());
+ buildOutputFromDevice(trace, in, builder, outputPorts, outputInstruction, ImmutableList.of());
}
}
@@ -474,7 +471,8 @@
*/
private void getGroupsFromInstructions(StaticPacketTrace trace, List<Group> groupsForDevice,
List<Instruction> instructions, DeviceId deviceId,
- TrafficSelector.Builder builder, List<PortNumber> outputPorts) {
+ TrafficSelector.Builder builder, List<PortNumber> outputPorts,
+ ConnectPoint in) {
List<Instruction> groupInstructionlist = new ArrayList<>();
for (Instruction instruction : instructions) {
log.debug("Considering Instruction {}", instruction);
@@ -484,11 +482,8 @@
//if the instruction is not group we need to update the packet or add the output
//to the possible outputs for this packet
if (instruction.type().equals(Instruction.Type.OUTPUT)) {
- outputPorts.add(((OutputInstruction) instruction).port());
- trace.addGroupOutputPath(deviceId,
- new GroupsInDevice(ConnectPoint.deviceConnectPoint(deviceId + "/" +
- ((OutputInstruction) instruction).port()),
- groupsForDevice, builder.build()));
+ buildOutputFromDevice(trace, in, builder, outputPorts,
+ (OutputInstruction) instruction, groupsForDevice);
} else {
builder = translateInstruction(builder, instruction);
}
@@ -512,12 +507,38 @@
//Cycle in each of the group's buckets and add them to the groups for this Device.
for (GroupBucket bucket : group.buckets().buckets()) {
getGroupsFromInstructions(trace, groupsForDevice, bucket.treatment().allInstructions(),
- deviceId, builder, outputPorts);
+ deviceId, builder, outputPorts, in);
}
}
}
/**
+ * Check if the output is the input port, if so adds a dop result message, otherwise builds
+ * a possible output from this device.
+ *
+ * @param trace the trace
+ * @param in the input connect point
+ * @param builder the packet builder
+ * @param outputPorts the list of output ports for this device
+ * @param outputInstruction the output instruction
+ * @param groupsForDevice
+ */
+ private void buildOutputFromDevice(StaticPacketTrace trace, ConnectPoint in, TrafficSelector.Builder builder,
+ List<PortNumber> outputPorts, OutputInstruction outputInstruction,
+ List<Group> groupsForDevice) {
+ ConnectPoint output = ConnectPoint.deviceConnectPoint(in.deviceId() + "/" +
+ outputInstruction.port());
+ if (output.equals(in)) {
+ trace.addResultMessage("Connect point out " + output + " is same as initial input " +
+ trace.getInitialConnectPoint());
+ } else {
+ trace.addGroupOutputPath(in.deviceId(),
+ new GroupsInDevice(output, groupsForDevice, builder.build()));
+ outputPorts.add(outputInstruction.port());
+ }
+ }
+
+ /**
* Applies all give instructions to the input packet.
*
* @param packet the input packet
diff --git a/src/test/java/org/onosproject/t3/impl/T3TestObjects.java b/src/test/java/org/onosproject/t3/impl/T3TestObjects.java
index b1edb86..7d24bbd 100644
--- a/src/test/java/org/onosproject/t3/impl/T3TestObjects.java
+++ b/src/test/java/org/onosproject/t3/impl/T3TestObjects.java
@@ -88,6 +88,24 @@
static final ConnectPoint SINGLE_FLOW_OUT_CP = ConnectPoint.deviceConnectPoint(SINGLE_FLOW_DEVICE + "/" + 2);
+ //same output as input
+ static final DeviceId SAME_OUTPUT_FLOW_DEVICE = DeviceId.deviceId("sameOutputDevice");
+
+ private static final TrafficTreatment SAME_OUTPUT_FLOW_TREATMENT = DefaultTrafficTreatment.builder()
+ .setOutput(PortNumber.portNumber(1)).build();
+ private static final FlowRule SAME_OUTPUT_FLOW = DefaultFlowEntry.builder().forDevice(SAME_OUTPUT_FLOW_DEVICE)
+ .forTable(0)
+ .withPriority(100)
+ .withSelector(SINGLE_FLOW_SELECTOR)
+ .withTreatment(SAME_OUTPUT_FLOW_TREATMENT)
+ .fromApp(new DefaultApplicationId(0, "TestApp"))
+ .makePermanent()
+ .build();
+ static final FlowEntry SAME_OUTPUT_FLOW_ENTRY = new DefaultFlowEntry(SAME_OUTPUT_FLOW);
+
+ static final ConnectPoint SAME_OUTPUT_FLOW_CP = ConnectPoint.deviceConnectPoint(SAME_OUTPUT_FLOW_DEVICE + "/" + 1);
+
+
//Dual Flow Test
static final DeviceId DUAL_FLOW_DEVICE = DeviceId.deviceId("DualFlowDevice");
private static final TrafficTreatment TRANSITION_FLOW_TREATMENT = DefaultTrafficTreatment.builder()
diff --git a/src/test/java/org/onosproject/t3/impl/TroubleshootManagerTest.java b/src/test/java/org/onosproject/t3/impl/TroubleshootManagerTest.java
index 382a468..63bcc32 100644
--- a/src/test/java/org/onosproject/t3/impl/TroubleshootManagerTest.java
+++ b/src/test/java/org/onosproject/t3/impl/TroubleshootManagerTest.java
@@ -106,9 +106,21 @@
StaticPacketTrace traceFail = mngr.trace(PACKET_OK, ConnectPoint.deviceConnectPoint(OFFLINE_DEVICE + "/1"));
assertNotNull("Trace should not be null", traceFail);
assertNull("Trace should have 0 output", traceFail.getGroupOuputs(SINGLE_FLOW_DEVICE));
+ }
+
+ /**
+ * Tests failure on same output.
+ */
+ @Test
+ public void sameOutput() {
+ StaticPacketTrace traceFail = mngr.trace(PACKET_OK, SAME_OUTPUT_FLOW_CP);
+ assertNotNull("Trace should not be null", traceFail);
+ assertTrue("Trace should be unsuccessful",
+ traceFail.resultMessage().contains("is same as initial input"));
log.info("trace {}", traceFail.resultMessage());
}
+
/**
* Tests failure on device with no flows.
*/
@@ -264,6 +276,8 @@
return ImmutableList.of(TOPO_GROUP_FLOW_ENTRY);
} else if (deviceId.equals(HARDWARE_DEVICE)) {
return ImmutableList.of(HARDWARE_ETH_FLOW_ENTRY, HARDWARE_FLOW_ENTRY);
+ } else if (deviceId.equals(SAME_OUTPUT_FLOW_DEVICE)) {
+ return ImmutableList.of(SAME_OUTPUT_FLOW_ENTRY);
}
return ImmutableList.of();
}