use of org.onosproject.fnl.base.TsLoopPacket in project onos by opennetworkinglab.
the class DefaultCheckLoop method processOneOutputInstruction.
/**
* Process one output instruction.
*
* Params are passed from processOneInstruction directly,
* and obey the same rules.
*
* @param instOne the instruction to be processed
* @param currentDeviceId id of the device we are now in
* @param initPkt the packet before being copied
* @param matchedPkt the packet which matched the flow entry,
* to which this instruction belongs
* @param isFindLoop indicate if it is invoked by findLoop method
* @param firstEntry the flow entry from which the packet is generated
* @return true, if a loop is discovered;
* false, 1. invoked by matchDeviceFlows method, and detected no loop;
* 2. invoked by findLoop method
*/
private boolean processOneOutputInstruction(Instruction instOne, DeviceId currentDeviceId, TsLoopPacket initPkt, TsLoopPacket matchedPkt, boolean isFindLoop, FlowEntry firstEntry) {
OutputInstruction instOutput = (OutputInstruction) instOne;
PortNumber instPort = instOutput.port();
if (!instPort.isLogical()) {
// single OUTPUT - NIC or normal port
Set<Link> dstLink = tsGetEgressLinks(new ConnectPoint(currentDeviceId, instPort));
if (!dstLink.isEmpty()) {
// TODO - now, just deal with the first destination.
// will there be more destinations?
Link dstThisLink = dstLink.iterator().next();
ConnectPoint dstPoint = dstThisLink.dst();
// check output to devices only (output to a host is normal)
if (isDevice(dstPoint)) {
PortCriterion oldInPort = updatePktInportPerHop(matchedPkt, dstPoint);
matchedPkt.pushPathLink(dstThisLink);
TsLoopPacket newNewPkt = matchedPkt.copyPacketMatch();
boolean loopFound = matchDeviceFlows(dstPoint.deviceId(), newNewPkt);
if (isFindLoop) {
if (loopFound) {
loops.add(newNewPkt);
updateExcludeDeviceSet(newNewPkt);
}
matchedPkt.resetLinkFlow(firstEntry);
} else {
if (loopFound) {
initPkt.handInLoopMatch(newNewPkt);
return true;
}
matchedPkt.popPathLink();
}
restorePktInportPerHop(matchedPkt, oldInPort);
}
} else {
if (!isFindLoop) {
// TODO - NEED
log.warn("no link connecting at device {}, port {}", currentDeviceId, instPort);
}
}
} else if (instPort.equals(PortNumber.IN_PORT)) {
// TODO - in the future,
// we may need to resolve this condition 1
log.warn("can not handle {} port now.", PortNumber.IN_PORT);
} else if (instPort.equals(PortNumber.NORMAL) || instPort.equals(PortNumber.FLOOD) || instPort.equals(PortNumber.ALL)) {
// TODO - in the future,
// we may need to resolve this condition 2
log.warn("can not handle {}/{}/{} now.", PortNumber.NORMAL, PortNumber.FLOOD, PortNumber.ALL);
}
return false;
}
use of org.onosproject.fnl.base.TsLoopPacket in project onos by opennetworkinglab.
the class DefaultCheckLoop method findLoop.
/**
* Enter of the loop checking algorithm.
*
* @return the set of loop results; empty, if there is no loop
*/
private Set<NetworkAnomaly> findLoop() {
getNetworkSnapshot();
loops = new HashSet<>();
excludeDeviceId = new HashSet<>();
for (Device device : accessDevices) {
if (excludeDeviceId.contains(device.id())) {
continue;
}
List<FlowEntry> availableFlowEntries = new ArrayList<>();
flowEntryInfo.get(device.id()).forEach(flowEntry -> {
if (flowEntry.state() == ADDED) {
availableFlowEntries.add(flowEntry);
}
});
List<FlowEntry> sortedFlowEntries = sortFlowTable(availableFlowEntries);
for (FlowEntry flow : sortedFlowEntries) {
TsLoopPacket pkt = matchBuilder(flow.selector().criteria(), null);
pkt.pushPathFlow(flow);
List<Instruction> inst = flow.treatment().immediate();
for (Instruction instOne : inst) {
// Attention !!!
// if you would like to modify the code here,
// please MAKE VERY SURE that you are clear with
// the relationship of any invoked methods, and
// the relationship of params which are passed in and out.
processOneInstruction(instOne, device.id(), null, pkt, true, flow);
}
}
}
return loops;
}
use of org.onosproject.fnl.base.TsLoopPacket in project onos by opennetworkinglab.
the class DefaultCheckLoop method matchDeviceFlows.
/**
* Iterate one by one at switch hops.
* Return whether we discover a Loop now or not.
*
* When flows form a loop,
* pkt is also a return value indicating the loop header.
*
* @param deviceId the device needed to be checked
* @param pkt virtual packet forwarded by switches
* @return true if a loop is discovered
*/
private boolean matchDeviceFlows(DeviceId deviceId, TsLoopPacket pkt) {
if (pkt.isPassedDevice(deviceId)) {
// Attention: pkt should be held outside
return true;
}
List<FlowEntry> availableFlowEntries = new ArrayList<>();
flowEntryInfo.get(deviceId).forEach(flowEntry -> {
if (flowEntry.state() == ADDED) {
availableFlowEntries.add(flowEntry);
}
});
List<FlowEntry> sortedFlowEntries = sortFlowTable(availableFlowEntries);
for (FlowEntry flowEntry : sortedFlowEntries) {
TsReturn<Boolean> isBigger = new TsReturn<>();
TsLoopPacket newPkt = pkt.copyPacketMatch();
if (!matchAndAddFlowEntry(flowEntry, newPkt, isBigger)) {
continue;
}
newPkt.pushPathFlow(flowEntry);
for (Instruction instOne : flowEntry.treatment().immediate()) {
// the relationship of params which are passed in and out.
if (processOneInstruction(instOne, deviceId, pkt, newPkt, false, null)) {
return true;
}
}
newPkt.popPathFlow();
if (!isBigger.getValue()) {
break;
}
}
return false;
}
Aggregations