use of org.onosproject.net.pi.runtime.PiActionParam in project onos by opennetworkinglab.
the class PiGroupTranslatorImplTest method outputMember.
private static PiActionProfileMember outputMember(int portNum) throws ImmutableByteSequence.ByteSequenceTrimException {
PiActionParam param = new PiActionParam(PORT, copyFrom(portNum).fit(PORT_BITWIDTH));
PiAction piAction = PiAction.builder().withId(INGRESS_WCMP_CONTROL_SET_EGRESS_PORT).withParameter(param).build();
return PiActionProfileMember.builder().forActionProfile(INGRESS_WCMP_CONTROL_WCMP_SELECTOR).withAction(piAction).withId(PiActionProfileMemberId.of(BASE_MEM_ID + portNum)).build();
}
use of org.onosproject.net.pi.runtime.PiActionParam in project onos by opennetworkinglab.
the class ActionCodec method encode.
@Override
protected P4RuntimeOuterClass.Action encode(PiAction piAction, Object ignored, PiPipeconf pipeconf, P4InfoBrowser browser) throws CodecException, P4InfoBrowser.NotFoundException {
final int actionId = browser.actions().getByName(piAction.id().toString()).getPreamble().getId();
final P4RuntimeOuterClass.Action.Builder actionMsgBuilder = P4RuntimeOuterClass.Action.newBuilder().setActionId(actionId);
for (PiActionParam p : piAction.parameters()) {
final P4InfoOuterClass.Action.Param paramInfo = browser.actionParams(actionId).getByName(p.id().toString());
final ByteString paramValue = ByteString.copyFrom(p.value().asReadOnlyBuffer());
if (!browser.isTypeString(paramInfo.getTypeName())) {
// Check size only if the param type is not a sdn_string
assertSize(format("param '%s' of action '%s'", p.id(), piAction.id()), paramValue, paramInfo.getBitwidth());
}
actionMsgBuilder.addParams(P4RuntimeOuterClass.Action.Param.newBuilder().setParamId(paramInfo.getId()).setValue(paramValue).build());
}
return actionMsgBuilder.build();
}
use of org.onosproject.net.pi.runtime.PiActionParam in project up4 by omec-project.
the class Up4TranslatorImpl method upfEntityToUp4TableEntry.
@Override
public PiTableEntry upfEntityToUp4TableEntry(UpfEntity entity) throws Up4TranslationException {
PiTableEntry.Builder tableEntryBuilder = PiTableEntry.builder();
PiAction.Builder actionBuilder = PiAction.builder();
PiMatchKey.Builder matchBuilder = PiMatchKey.builder();
switch(entity.type()) {
case INTERFACE:
tableEntryBuilder.forTable(PRE_QOS_PIPE_INTERFACES);
UpfInterface upfIntf = (UpfInterface) entity;
byte direction;
byte srcIface;
actionBuilder.withId(PRE_QOS_PIPE_SET_SOURCE_IFACE);
if (upfIntf.isAccess()) {
srcIface = IFACE_ACCESS;
direction = DIRECTION_UPLINK;
} else if (upfIntf.isCore()) {
srcIface = IFACE_CORE;
direction = DIRECTION_DOWNLINK;
} else {
throw new Up4TranslationException("UPF Interface is not Access nor CORE: " + upfIntf);
}
actionBuilder.withParameter(new PiActionParam(SRC_IFACE, srcIface)).withParameter(new PiActionParam(DIRECTION, direction)).withParameter(new PiActionParam(SLICE_ID, (byte) upfIntf.sliceId()));
matchBuilder.addFieldMatch(new PiLpmFieldMatch(HDR_IPV4_DST_PREFIX, ImmutableByteSequence.copyFrom(upfIntf.prefix().address().toOctets()), upfIntf.prefix().prefixLength()));
break;
case SESSION_UPLINK:
tableEntryBuilder.forTable(PRE_QOS_PIPE_SESSIONS_UPLINK);
UpfSessionUplink sessionUplink = (UpfSessionUplink) entity;
matchBuilder.addFieldMatch(new PiExactFieldMatch(HDR_N3_ADDRESS, ImmutableByteSequence.copyFrom(sessionUplink.tunDstAddr().toOctets()))).addFieldMatch(new PiExactFieldMatch(HDR_TEID, ImmutableByteSequence.copyFrom(sessionUplink.teid())));
if (sessionUplink.needsDropping()) {
actionBuilder.withId(PRE_QOS_PIPE_SET_SESSION_UPLINK_DROP);
} else {
actionBuilder.withId(PRE_QOS_PIPE_SET_SESSION_UPLINK);
actionBuilder.withParameter(new PiActionParam(SESSION_METER_IDX, sessionUplink.sessionMeterIdx()));
}
break;
case SESSION_DOWNLINK:
tableEntryBuilder.forTable(PRE_QOS_PIPE_SESSIONS_DOWNLINK);
UpfSessionDownlink sessionDownlink = (UpfSessionDownlink) entity;
matchBuilder.addFieldMatch(new PiExactFieldMatch(HDR_UE_ADDRESS, ImmutableByteSequence.copyFrom(sessionDownlink.ueAddress().toOctets())));
if (sessionDownlink.needsDropping() && sessionDownlink.needsBuffering()) {
log.error("We don't support DROP + BUFF on the UP4 northbound! Defaulting to only BUFF");
actionBuilder.withId(PRE_QOS_PIPE_SET_SESSION_DOWNLINK_BUFF);
actionBuilder.withParameter(new PiActionParam(SESSION_METER_IDX, sessionDownlink.sessionMeterIdx()));
} else if (sessionDownlink.needsDropping()) {
actionBuilder.withId(PRE_QOS_PIPE_SET_SESSION_DOWNLINK_DROP);
} else {
actionBuilder.withParameter(new PiActionParam(SESSION_METER_IDX, sessionDownlink.sessionMeterIdx()));
if (sessionDownlink.needsBuffering()) {
actionBuilder.withId(PRE_QOS_PIPE_SET_SESSION_DOWNLINK_BUFF);
} else {
actionBuilder.withParameter(new PiActionParam(TUNNEL_PEER_ID, ImmutableByteSequence.copyFrom(sessionDownlink.tunPeerId())));
actionBuilder.withId(PRE_QOS_PIPE_SET_SESSION_DOWNLINK);
}
}
break;
case TERMINATION_UPLINK:
tableEntryBuilder.forTable(PRE_QOS_PIPE_TERMINATIONS_UPLINK);
UpfTerminationUplink upfTerminationUl = (UpfTerminationUplink) entity;
matchBuilder.addFieldMatch(new PiExactFieldMatch(HDR_UE_ADDRESS, ImmutableByteSequence.copyFrom(upfTerminationUl.ueSessionId().toOctets()))).addFieldMatch(new PiExactFieldMatch(HDR_APP_ID, ImmutableByteSequence.copyFrom(upfTerminationUl.applicationId())));
actionBuilder.withParameter(new PiActionParam(CTR_IDX, upfTerminationUl.counterId()));
if (upfTerminationUl.needsDropping()) {
actionBuilder.withId(PRE_QOS_PIPE_UPLINK_TERM_DROP);
} else {
if (upfTerminationUl.trafficClass() != null) {
actionBuilder.withId(PRE_QOS_PIPE_UPLINK_TERM_FWD);
actionBuilder.withParameter(new PiActionParam(TC, upfTerminationUl.trafficClass()));
} else {
actionBuilder.withId(PRE_QOS_PIPE_UPLINK_TERM_FWD_NO_TC);
}
actionBuilder.withParameter(new PiActionParam(APP_METER_IDX, upfTerminationUl.appMeterIdx()));
}
break;
case TERMINATION_DOWNLINK:
tableEntryBuilder.forTable(PRE_QOS_PIPE_TERMINATIONS_DOWNLINK);
UpfTerminationDownlink upfTerminationDl = (UpfTerminationDownlink) entity;
matchBuilder.addFieldMatch(new PiExactFieldMatch(HDR_UE_ADDRESS, ImmutableByteSequence.copyFrom(upfTerminationDl.ueSessionId().toOctets()))).addFieldMatch(new PiExactFieldMatch(HDR_APP_ID, ImmutableByteSequence.copyFrom(upfTerminationDl.applicationId())));
actionBuilder.withParameter(new PiActionParam(CTR_IDX, upfTerminationDl.counterId()));
if (upfTerminationDl.needsDropping()) {
actionBuilder.withId(PRE_QOS_PIPE_DOWNLINK_TERM_DROP);
} else {
actionBuilder.withParameter(new PiActionParam(TEID, upfTerminationDl.teid())).withParameter(new PiActionParam(QFI, upfTerminationDl.qfi()));
if (upfTerminationDl.trafficClass() != null) {
actionBuilder.withId(PRE_QOS_PIPE_DOWNLINK_TERM_FWD);
actionBuilder.withParameter(new PiActionParam(TC, upfTerminationDl.trafficClass()));
} else {
actionBuilder.withId(PRE_QOS_PIPE_DOWNLINK_TERM_FWD_NO_TC);
}
actionBuilder.withParameter(new PiActionParam(APP_METER_IDX, upfTerminationDl.appMeterIdx()));
}
break;
case TUNNEL_PEER:
tableEntryBuilder.forTable(PRE_QOS_PIPE_TUNNEL_PEERS);
UpfGtpTunnelPeer gtpTunnelPeer = (UpfGtpTunnelPeer) entity;
matchBuilder.addFieldMatch(new PiExactFieldMatch(HDR_TUNNEL_PEER_ID, ImmutableByteSequence.copyFrom(gtpTunnelPeer.tunPeerId())));
actionBuilder.withId(PRE_QOS_PIPE_LOAD_TUNNEL_PARAM).withParameter(new PiActionParam(SRC_ADDR, gtpTunnelPeer.src().toOctets())).withParameter(new PiActionParam(DST_ADDR, gtpTunnelPeer.dst().toOctets())).withParameter(new PiActionParam(SPORT, gtpTunnelPeer.srcPort()));
break;
case APPLICATION:
tableEntryBuilder.forTable(PRE_QOS_PIPE_APPLICATIONS);
UpfApplication application = (UpfApplication) entity;
tableEntryBuilder.withPriority(application.priority());
actionBuilder.withId(PRE_QOS_PIPE_SET_APP_ID).withParameter(new PiActionParam(APP_ID, application.appId()));
matchBuilder.addFieldMatch(new PiExactFieldMatch(HDR_SLICE_ID, ImmutableByteSequence.copyFrom((byte) application.sliceId())));
if (application.ip4Prefix().isPresent()) {
Ip4Prefix ipPrefix = application.ip4Prefix().get();
matchBuilder.addFieldMatch(new PiLpmFieldMatch(HDR_APP_IP_ADDR, ImmutableByteSequence.copyFrom(ipPrefix.address().toOctets()), ipPrefix.prefixLength()));
}
if (application.l4PortRange().isPresent()) {
Range<Short> portRange = application.l4PortRange().get();
matchBuilder.addFieldMatch(new PiRangeFieldMatch(HDR_APP_L4_PORT, ImmutableByteSequence.copyFrom(portRange.lowerEndpoint()), ImmutableByteSequence.copyFrom(portRange.upperEndpoint())));
}
if (application.ipProto().isPresent()) {
byte ipProto = application.ipProto().get();
matchBuilder.addFieldMatch(new PiTernaryFieldMatch(HDR_APP_IP_PROTO, ImmutableByteSequence.copyFrom(ipProto), ImmutableByteSequence.ofOnes(1)));
}
break;
case SESSION_METER:
case APPLICATION_METER:
case COUNTER:
default:
throw new Up4TranslationException("Attempting to translate an unsupported UPF entity to a table entry! " + entity);
}
return tableEntryBuilder.withMatchKey(matchBuilder.build()).withAction(actionBuilder.build()).build();
}
use of org.onosproject.net.pi.runtime.PiActionParam 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.pi.runtime.PiActionParam in project onos by opennetworkinglab.
the class MyTunnelApp method insertTunnelIngressRule.
/**
* Generates and insert a flow rule to perform the tunnel INGRESS function
* for the given switch, destination IP address and tunnel ID.
*
* @param switchId switch ID
* @param dstIpAddr IP address to forward inside the tunnel
* @param tunId tunnel ID
*/
private void insertTunnelIngressRule(DeviceId switchId, IpAddress dstIpAddr, int tunId) {
PiTableId tunnelIngressTableId = PiTableId.of("c_ingress.t_tunnel_ingress");
// Longest prefix match on IPv4 dest address.
PiMatchFieldId ipDestMatchFieldId = PiMatchFieldId.of("hdr.ipv4.dst_addr");
PiCriterion match = PiCriterion.builder().matchLpm(ipDestMatchFieldId, dstIpAddr.toOctets(), 32).build();
PiActionParam tunIdParam = new PiActionParam(PiActionParamId.of("tun_id"), tunId);
PiActionId ingressActionId = PiActionId.of("c_ingress.my_tunnel_ingress");
PiAction action = PiAction.builder().withId(ingressActionId).withParameter(tunIdParam).build();
log.info("Inserting INGRESS rule on switch {}: table={}, match={}, action={}", switchId, tunnelIngressTableId, match, action);
insertPiFlowRule(switchId, tunnelIngressTableId, match, action);
}
Aggregations