use of org.onosproject.net.flow.instructions.Instruction in project onos by opennetworkinglab.
the class OplinkPowerConfigUtil method findFlow.
/**
* Find matching flow on device.
*
* @param portNum the port number
* @param och channel signal
* @return flow entry
*/
private FlowEntry findFlow(PortNumber portNum, OchSignal och) {
final DriverHandler handler = behaviour.handler();
FlowRuleService service = handler.get(FlowRuleService.class);
Iterable<FlowEntry> flowEntries = service.getFlowEntries(handler.data().deviceId());
// Return first matching flow
for (FlowEntry entry : flowEntries) {
TrafficSelector selector = entry.selector();
OchSignalCriterion entrySigid = (OchSignalCriterion) selector.getCriterion(Criterion.Type.OCH_SIGID);
// Check channel
if (entrySigid != null && och.equals(entrySigid.lambda())) {
// Check input port
PortCriterion entryPort = (PortCriterion) selector.getCriterion(Criterion.Type.IN_PORT);
if (entryPort != null && portNum.equals(entryPort.port())) {
return entry;
}
// Check output port
TrafficTreatment treatment = entry.treatment();
for (Instruction instruction : treatment.allInstructions()) {
if (instruction.type() == Instruction.Type.OUTPUT && ((Instructions.OutputInstruction) instruction).port().equals(portNum)) {
return entry;
}
}
}
}
log.warn("No matching flow found");
return null;
}
use of org.onosproject.net.flow.instructions.Instruction 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;
}
use of org.onosproject.net.flow.instructions.Instruction in project onos by opennetworkinglab.
the class PipelineInterpreterImpl method mapTreatment.
@Override
public PiAction mapTreatment(TrafficTreatment treatment, PiTableId piTableId) throws PiInterpreterException {
if (piTableId != TABLE_L2_FWD_ID) {
throw new PiInterpreterException("Can map treatments only for 't_l2_fwd' table");
}
if (treatment.allInstructions().size() == 0) {
// 0 instructions means "NoAction"
return PiAction.builder().withId(ACT_ID_NOP).build();
} else if (treatment.allInstructions().size() > 1) {
// We understand treatments with only 1 instruction.
throw new PiInterpreterException("Treatment has multiple instructions");
}
// Get the first and only instruction.
Instruction instruction = treatment.allInstructions().get(0);
if (instruction.type() != OUTPUT) {
// We can map only instructions of type OUTPUT.
throw new PiInterpreterException(format("Instruction of type '%s' not supported", instruction.type()));
}
OutputInstruction outInstruction = (OutputInstruction) instruction;
PortNumber port = outInstruction.port();
if (!port.isLogical()) {
return PiAction.builder().withId(ACT_ID_SET_EGRESS_PORT).withParameter(new PiActionParam(ACT_PARAM_ID_PORT, copyFrom(port.toLong()))).build();
} else if (port.equals(CONTROLLER)) {
return PiAction.builder().withId(ACT_ID_SEND_TO_CPU).build();
} else {
throw new PiInterpreterException(format("Output on logical port '%s' not supported", port));
}
}
use of org.onosproject.net.flow.instructions.Instruction in project onos by opennetworkinglab.
the class PipelineInterpreterImpl method mapOutboundPacket.
@Override
public Collection<PiPacketOperation> mapOutboundPacket(OutboundPacket packet) throws PiInterpreterException {
TrafficTreatment treatment = packet.treatment();
// We support only packet-out with OUTPUT instructions.
if (treatment.allInstructions().size() != 1 && treatment.allInstructions().get(0).type() != OUTPUT) {
throw new PiInterpreterException("Treatment not supported: " + treatment.toString());
}
Instruction instruction = treatment.allInstructions().get(0);
PortNumber port = ((OutputInstruction) instruction).port();
List<PiPacketOperation> piPacketOps = Lists.newArrayList();
if (!port.isLogical()) {
piPacketOps.add(createPiPacketOp(packet.data(), port.toLong()));
} else if (port.equals(FLOOD)) {
// Since mytunnel.p4 does not support flooding, we create a packet
// operation for each switch port.
DeviceService deviceService = handler().get(DeviceService.class);
DeviceId deviceId = packet.sendThrough();
for (Port p : deviceService.getPorts(deviceId)) {
piPacketOps.add(createPiPacketOp(packet.data(), p.number().toLong()));
}
} else {
throw new PiInterpreterException(format("Output on logical port '%s' not supported", port));
}
return piPacketOps;
}
use of org.onosproject.net.flow.instructions.Instruction in project onos by opennetworkinglab.
the class ChannelData method fromFlow.
/**
* Returns a ChannelData representation from a flow rule. The rule must contain
* a Criterion.Type.IN_PORT selector, Criterion.Type.OCH_SIGID selector, and
* Instruction.Type.OUTPUT instruction.
*
* @param rule the flow rule representing the connection
* @return ChannelData representation of the connection
*/
public static ChannelData fromFlow(FlowRule rule) {
checkNotNull(rule);
Criterion in = rule.selector().getCriterion(Criterion.Type.IN_PORT);
checkNotNull(in);
PortNumber inPort = ((PortCriterion) in).port();
Criterion och = rule.selector().getCriterion(Criterion.Type.OCH_SIGID);
OchSignal ochSignal = och == null ? null : ((OchSignalCriterion) och).lambda();
PortNumber outPort = null;
List<Instruction> instructions = rule.treatment().allInstructions();
for (Instruction ins : instructions) {
if (ins.type() == Instruction.Type.OUTPUT) {
outPort = ((Instructions.OutputInstruction) ins).port();
}
}
checkNotNull(outPort);
return new ChannelData(inPort, outPort, ochSignal);
}
Aggregations