use of org.onosproject.net.pi.runtime.PiAction in project onos by opennetworkinglab.
the class MyTunnelApp method insertTunnelForwardRule.
/**
* Generates and insert a flow rule to perform the tunnel FORWARD/EGRESS
* function for the given switch, output port address and tunnel ID.
*
* @param switchId switch ID
* @param outPort output port where to forward tunneled packets
* @param tunId tunnel ID
* @param isEgress if true, perform tunnel egress action, otherwise forward
* packet as is to port
*/
private void insertTunnelForwardRule(DeviceId switchId, PortNumber outPort, int tunId, boolean isEgress) {
PiTableId tunnelForwardTableId = PiTableId.of("c_ingress.t_tunnel_fwd");
// Exact match on tun_id
PiMatchFieldId tunIdMatchFieldId = PiMatchFieldId.of("hdr.my_tunnel.tun_id");
PiCriterion match = PiCriterion.builder().matchExact(tunIdMatchFieldId, tunId).build();
// Action depend on isEgress parameter.
// if true, perform tunnel egress action on the given outPort, otherwise
// simply forward packet as is (set_out_port action).
PiActionParamId portParamId = PiActionParamId.of("port");
PiActionParam portParam = new PiActionParam(portParamId, (short) outPort.toLong());
final PiAction action;
if (isEgress) {
// Tunnel egress action.
// Remove MyTunnel header and forward to outPort.
PiActionId egressActionId = PiActionId.of("c_ingress.my_tunnel_egress");
action = PiAction.builder().withId(egressActionId).withParameter(portParam).build();
} else {
// Tunnel transit action.
// Forward the packet as is to outPort.
/*
* TODO EXERCISE: create action object for the transit case.
* Look at the t_tunnel_fwd table in the P4 program. Which of the 3
* actions can be used to simply set the output port? Get the full
* action name from the P4Info file, and use that when creating the
* PiActionId object. When creating the PiAction object, remember to
* add all action parameters as defined in the P4 program.
*
* Hint: the code will be similar to the case when isEgress is true.
*/
// Replace null with your solution.
action = null;
}
log.info("Inserting {} rule on switch {}: table={}, match={}, action={}", isEgress ? "EGRESS" : "TRANSIT", switchId, tunnelForwardTableId, match, action);
insertPiFlowRule(switchId, tunnelForwardTableId, match, action);
}
use of org.onosproject.net.pi.runtime.PiAction in project onos by opennetworkinglab.
the class EncodeInstructionCodecHelper method encodePi.
/**
* Encode a protocol-independent instruction.
*
* @param result json node that the instruction attributes are added to
*/
private void encodePi(ObjectNode result) {
PiInstruction piInstruction = (PiInstruction) instruction;
result.put(InstructionCodec.SUBTYPE, piInstruction.action().type().name());
switch(piInstruction.action().type()) {
case ACTION:
final PiAction piAction = (PiAction) piInstruction.action();
result.put(InstructionCodec.PI_ACTION_ID, piAction.id().id());
final ObjectNode jsonActionParams = context.mapper().createObjectNode();
for (PiActionParam actionParam : piAction.parameters()) {
jsonActionParams.put(actionParam.id().id(), HexString.toHexString(actionParam.value().asArray(), null));
}
result.set(InstructionCodec.PI_ACTION_PARAMS, jsonActionParams);
break;
case ACTION_PROFILE_GROUP_ID:
final PiActionProfileGroupId groupId = (PiActionProfileGroupId) piInstruction.action();
result.put(InstructionCodec.PI_ACTION_PROFILE_GROUP_ID, groupId.id());
break;
case ACTION_PROFILE_MEMBER_ID:
final PiActionProfileMemberId memberId = (PiActionProfileMemberId) piInstruction.action();
result.put(InstructionCodec.PI_ACTION_PROFILE_MEMBER_ID, memberId.id());
break;
// TODO: implement JSON encoder for ACTION_SET
default:
throw new IllegalArgumentException("Cannot convert protocol-independent subtype of" + piInstruction.action().type().name());
}
}
use of org.onosproject.net.pi.runtime.PiAction in project onos by opennetworkinglab.
the class InstructionJsonMatcher method matchPiInstruction.
/**
* Matches the contents of a protocol-independent instruction.
*
* @param instructionJson JSON instruction to match
* @param description Description object used for recording errors
* @return true if contents match, false otherwise
*/
private boolean matchPiInstruction(JsonNode instructionJson, Description description) {
PiInstruction instructionToMatch = (PiInstruction) instruction;
final String jsonSubtype = instructionJson.get("subtype").textValue();
if (!instructionToMatch.action().type().name().equals(jsonSubtype)) {
description.appendText("subtype was " + jsonSubtype);
return false;
}
final String jsonType = instructionJson.get("type").textValue();
if (!instructionToMatch.type().name().equals(jsonType)) {
description.appendText("type was " + jsonType);
return false;
}
switch(instructionToMatch.action().type()) {
case ACTION:
if (!Objects.equals(instructionJson.get("actionId").textValue(), ((PiAction) instructionToMatch.action()).id().id())) {
description.appendText("action was " + ((PiAction) instructionToMatch.action()).id().id());
return false;
}
Collection<PiActionParam> piActionParams = ((PiAction) instructionToMatch.action()).parameters();
JsonNode jsonParams = instructionJson.get("actionParams");
for (PiActionParam actionParam : piActionParams) {
if (!Objects.equals(copyFrom(HexString.fromHexString(jsonParams.get(actionParam.id().id()).textValue(), null)), actionParam.value())) {
description.appendText("action param value was " + actionParam.value());
return false;
}
}
break;
case ACTION_PROFILE_GROUP_ID:
if (!Objects.equals(instructionJson.get("groupId").asInt(), ((PiActionProfileGroupId) instructionToMatch.action()).id())) {
description.appendText("action profile group id was " + ((PiActionProfileGroupId) instructionToMatch.action()).id());
return false;
}
break;
case ACTION_PROFILE_MEMBER_ID:
if (!Objects.equals(instructionJson.get("memberId").asInt(), ((PiActionProfileMemberId) instructionToMatch.action()).id())) {
description.appendText("action profile member id was " + ((PiActionProfileMemberId) instructionToMatch.action()).id());
return false;
}
break;
default:
description.appendText("type was " + jsonType);
return false;
}
return true;
}
use of org.onosproject.net.pi.runtime.PiAction in project onos by opennetworkinglab.
the class InstructionCodecTest method piInstructionDecodingTest.
/**
* Tests the decoding of protocol-independent instructions.
*/
@Test
public void piInstructionDecodingTest() throws IOException {
Instruction actionInstruction = getInstruction("PiActionInstruction.json");
Assert.assertThat(actionInstruction.type(), is(Instruction.Type.PROTOCOL_INDEPENDENT));
PiTableAction action = ((PiInstruction) actionInstruction).action();
Assert.assertThat(action.type(), is(PiTableAction.Type.ACTION));
Assert.assertThat(((PiAction) action).id().id(), is("set_egress_port"));
Assert.assertThat(((PiAction) action).parameters().size(), is(1));
Collection<PiActionParam> actionParams = ((PiAction) action).parameters();
PiActionParam actionParam = actionParams.iterator().next();
Assert.assertThat(actionParam.id().id(), is("port"));
Assert.assertThat(actionParam.value(), is(copyFrom((byte) 0x1)));
Instruction actionGroupIdInstruction = getInstruction("PiActionProfileGroupIdInstruction.json");
Assert.assertThat(actionInstruction.type(), is(Instruction.Type.PROTOCOL_INDEPENDENT));
PiTableAction actionGroupId = ((PiInstruction) actionGroupIdInstruction).action();
Assert.assertThat(actionGroupId.type(), is(PiTableAction.Type.ACTION_PROFILE_GROUP_ID));
Assert.assertThat(((PiActionProfileGroupId) actionGroupId).id(), is(100));
Instruction actionMemberIdInstruction = getInstruction("PiActionProfileMemberIdInstruction.json");
Assert.assertThat(actionInstruction.type(), is(Instruction.Type.PROTOCOL_INDEPENDENT));
PiTableAction actionMemberId = ((PiInstruction) actionMemberIdInstruction).action();
Assert.assertThat(actionMemberId.type(), is(PiTableAction.Type.ACTION_PROFILE_MEMBER_ID));
Assert.assertThat(((PiActionProfileMemberId) actionMemberId).id(), is(100));
}
use of org.onosproject.net.pi.runtime.PiAction in project onos by opennetworkinglab.
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(FabricConstants.PORT_NUM, outPort.toLong()));
if (ethDst != null && ethSrc != null) {
actionBuilder.withParameter(new PiActionParam(FabricConstants.SMAC, ethSrc.mac().toBytes()));
actionBuilder.withParameter(new PiActionParam(FabricConstants.DMAC, ethDst.mac().toBytes()));
// routing_hashed
return actionBuilder.withId(simple ? FabricConstants.FABRIC_INGRESS_NEXT_ROUTING_SIMPLE : FabricConstants.FABRIC_INGRESS_NEXT_ROUTING_HASHED).build();
} else {
// output_hashed
return actionBuilder.withId(simple ? FabricConstants.FABRIC_INGRESS_NEXT_OUTPUT_SIMPLE : FabricConstants.FABRIC_INGRESS_NEXT_OUTPUT_HASHED).build();
}
}
Aggregations