use of org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsHeaderInstruction in project onos by opennetworkinglab.
the class Ofdpa2Pipeline method processEthTypeSpecificInternal.
/**
* Internal implementation of processEthTypeSpecific.
* <p>
* Wildcarded IPv4_DST is not supported in OFDPA i12. Therefore, we break
* the rule into 0.0.0.0/1 and 128.0.0.0/1.
* The allowDefaultRoute must be set to false for OFDPA i12.
* </p>
*
* @param fwd the forwarding objective
* @param allowDefaultRoute allow wildcarded IPv4_DST or not
* @param mplsNextTable next MPLS table
* @return A collection of flow rules, or an empty set
*/
protected Collection<FlowRule> processEthTypeSpecificInternal(ForwardingObjective fwd, boolean allowDefaultRoute, int mplsNextTable) {
TrafficSelector selector = fwd.selector();
EthTypeCriterion ethType = (EthTypeCriterion) selector.getCriterion(Criterion.Type.ETH_TYPE);
boolean emptyGroup = false;
int forTableId;
TrafficSelector.Builder filteredSelector = DefaultTrafficSelector.builder();
TrafficTreatment.Builder tb = DefaultTrafficTreatment.builder();
TrafficSelector.Builder complementarySelector = DefaultTrafficSelector.builder();
if (ethType.ethType().toShort() == Ethernet.TYPE_IPV4) {
if (buildIpv4Selector(filteredSelector, complementarySelector, fwd, allowDefaultRoute) < 0) {
return Collections.emptyList();
}
// We need to set properly the next table
IpPrefix ipv4Dst = ((IPCriterion) selector.getCriterion(Criterion.Type.IPV4_DST)).ip();
if (ipv4Dst.isMulticast()) {
forTableId = MULTICAST_ROUTING_TABLE;
} else {
forTableId = UNICAST_ROUTING_TABLE;
}
// TODO decrementing IP ttl is done automatically for routing, this
// action is ignored or rejected in ofdpa as it is not fully implemented
// if (fwd.treatment() != null) {
// for (Instruction instr : fwd.treatment().allInstructions()) {
// if (instr instanceof L3ModificationInstruction &&
// ((L3ModificationInstruction) instr).subtype() == L3SubType.DEC_TTL) {
// tb.deferred().add(instr);
// }
// }
// }
} else if (ethType.ethType().toShort() == Ethernet.TYPE_IPV6) {
if (buildIpv6Selector(filteredSelector, fwd) < 0) {
return Collections.emptyList();
}
// We need to set the proper next table
IpPrefix ipv6Dst = ((IPCriterion) selector.getCriterion(Criterion.Type.IPV6_DST)).ip();
if (ipv6Dst.isMulticast()) {
forTableId = MULTICAST_ROUTING_TABLE;
} else {
forTableId = UNICAST_ROUTING_TABLE;
}
// TODO decrementing IP ttl is done automatically for routing, this
// action is ignored or rejected in ofdpa as it is not fully implemented
// if (fwd.treatment() != null) {
// for (Instruction instr : fwd.treatment().allInstructions()) {
// if (instr instanceof L3ModificationInstruction &&
// ((L3ModificationInstruction) instr).subtype() == L3SubType.DEC_TTL) {
// tb.deferred().add(instr);
// }
// }
// }
} else {
filteredSelector.matchEthType(Ethernet.MPLS_UNICAST).matchMplsLabel(((MplsCriterion) selector.getCriterion(Criterion.Type.MPLS_LABEL)).label());
MplsBosCriterion bos = (MplsBosCriterion) selector.getCriterion(MPLS_BOS);
if (bos != null && requireMplsBosMatch()) {
filteredSelector.matchMplsBos(bos.mplsBos());
}
forTableId = MPLS_TABLE_1;
log.debug("processing MPLS specific forwarding objective {} -> next:{}" + " in dev {}", fwd.id(), fwd.nextId(), deviceId);
if (fwd.treatment() != null) {
for (Instruction instr : fwd.treatment().allInstructions()) {
if (instr instanceof L2ModificationInstruction && ((L2ModificationInstruction) instr).subtype() == L2SubType.MPLS_POP) {
// setting the MPLS_TYPE so pop can happen down the pipeline
if (requireMplsPop()) {
if (mplsNextTable == MPLS_TYPE_TABLE && isNotMplsBos(selector)) {
tb.immediate().popMpls();
}
} else {
// Skip mpls pop action for mpls_unicast label
if (instr instanceof ModMplsHeaderInstruction && !((ModMplsHeaderInstruction) instr).ethernetType().equals(EtherType.MPLS_UNICAST.ethType())) {
tb.immediate().add(instr);
}
}
}
if (requireMplsTtlModification()) {
if (instr instanceof L3ModificationInstruction && ((L3ModificationInstruction) instr).subtype() == L3SubType.DEC_TTL) {
// FIXME Should modify the app to send the correct DEC_MPLS_TTL instruction
tb.immediate().decMplsTtl();
}
if (instr instanceof L3ModificationInstruction && ((L3ModificationInstruction) instr).subtype() == L3SubType.TTL_IN) {
tb.immediate().add(instr);
}
}
}
}
}
if (fwd.nextId() != null) {
NextGroup next = getGroupForNextObjective(fwd.nextId());
if (next != null) {
List<Deque<GroupKey>> gkeys = appKryo.deserialize(next.data());
// we only need the top level group's key to point the flow to it
Group group = groupService.getGroup(deviceId, gkeys.get(0).peekFirst());
if (group == null) {
log.warn("Group with key:{} for next-id:{} not found in dev:{}", gkeys.get(0).peekFirst(), fwd.nextId(), deviceId);
fail(fwd, ObjectiveError.GROUPMISSING);
return Collections.emptySet();
}
if (isNotMplsBos(selector) && group.type().equals(SELECT)) {
log.warn("SR CONTINUE case cannot be handled as MPLS ECMP " + "is not implemented in OF-DPA yet. Aborting flow {} -> next:{} " + "in this device {}", fwd.id(), fwd.nextId(), deviceId);
fail(fwd, ObjectiveError.FLOWINSTALLATIONFAILED);
return Collections.emptySet();
}
tb.deferred().group(group.id());
// retrying flows may be necessary due to bug CORD-554
if (gkeys.size() == 1 && gkeys.get(0).size() == 1) {
if (shouldRetry()) {
log.warn("Found empty group 0x{} in dev:{} .. will retry fwd:{}", Integer.toHexString(group.id().id()), deviceId, fwd.id());
emptyGroup = true;
}
}
} else {
log.warn("Cannot find group for nextId:{} in dev:{}. Aborting fwd:{}", fwd.nextId(), deviceId, fwd.id());
fail(fwd, ObjectiveError.FLOWINSTALLATIONFAILED);
return Collections.emptySet();
}
}
if (forTableId == MPLS_TABLE_1) {
if (mplsNextTable == MPLS_L3_TYPE_TABLE) {
Ofdpa3SetMplsType setMplsType = new Ofdpa3SetMplsType(Ofdpa3MplsType.L3_PHP);
// set mpls type as apply_action
tb.immediate().extension(setMplsType, deviceId);
}
tb.transition(mplsNextTable);
} else {
tb.transition(ACL_TABLE);
}
if (fwd.treatment() != null && fwd.treatment().clearedDeferred()) {
if (supportsUnicastBlackHole()) {
tb.wipeDeferred();
} else {
log.warn("Clear Deferred is not supported Unicast Routing Table on device {}", deviceId);
return Collections.emptySet();
}
}
FlowRule.Builder ruleBuilder = DefaultFlowRule.builder().fromApp(fwd.appId()).withPriority(fwd.priority()).forDevice(deviceId).withSelector(filteredSelector.build()).withTreatment(tb.build()).forTable(forTableId);
if (fwd.permanent()) {
ruleBuilder.makePermanent();
} else {
ruleBuilder.makeTemporary(fwd.timeout());
}
Collection<FlowRule> flowRuleCollection = new ArrayList<>();
flowRuleCollection.add(ruleBuilder.build());
if (!allowDefaultRoute) {
flowRuleCollection.add(defaultRoute(fwd, complementarySelector, forTableId, tb));
log.debug("Default rule 0.0.0.0/0 is being installed two rules");
}
if (emptyGroup) {
retryExecutorService.schedule(new RetryFlows(fwd, flowRuleCollection), RETRY_MS, TimeUnit.MILLISECONDS);
}
return flowRuleCollection;
}
use of org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsHeaderInstruction in project onos by opennetworkinglab.
the class InstructionJsonMatcher method matchModMplsHeaderInstruction.
/**
* Matches the contents of a push header instruction.
*
* @param instructionJson JSON instruction to match
* @param description Description object used for recording errors
* @return true if contents match, false otherwise
*/
private boolean matchModMplsHeaderInstruction(JsonNode instructionJson, Description description) {
ModMplsHeaderInstruction instructionToMatch = (ModMplsHeaderInstruction) instruction;
final String jsonSubtype = instructionJson.get("subtype").textValue();
if (!instructionToMatch.subtype().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;
}
final JsonNode ethJson = instructionJson.get("ethernetType");
if (ethJson == null) {
description.appendText("ethernetType was not null");
return false;
}
if (instructionToMatch.ethernetType().toShort() != ethJson.asInt()) {
description.appendText("ethernetType was " + ethJson);
return false;
}
return true;
}
use of org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsHeaderInstruction in project onos by opennetworkinglab.
the class FlowModBuilderVer13 method buildL2Modification.
protected OFAction buildL2Modification(Instruction i) {
L2ModificationInstruction l2m = (L2ModificationInstruction) i;
ModEtherInstruction eth;
OFOxm<?> oxm = null;
switch(l2m.subtype()) {
case ETH_DST:
eth = (ModEtherInstruction) l2m;
oxm = factory().oxms().ethDst(MacAddress.of(eth.mac().toLong()));
break;
case ETH_SRC:
eth = (ModEtherInstruction) l2m;
oxm = factory().oxms().ethSrc(MacAddress.of(eth.mac().toLong()));
break;
case VLAN_ID:
ModVlanIdInstruction vlanId = (ModVlanIdInstruction) l2m;
oxm = factory().oxms().vlanVid(OFVlanVidMatch.ofVlan(vlanId.vlanId().toShort()));
break;
case VLAN_PCP:
ModVlanPcpInstruction vlanPcp = (ModVlanPcpInstruction) l2m;
oxm = factory().oxms().vlanPcp(VlanPcp.of(vlanPcp.vlanPcp()));
break;
case MPLS_PUSH:
ModMplsHeaderInstruction pushHeaderInstructions = (ModMplsHeaderInstruction) l2m;
return factory().actions().pushMpls(EthType.of(pushHeaderInstructions.ethernetType().toShort()));
case MPLS_POP:
ModMplsHeaderInstruction popHeaderInstructions = (ModMplsHeaderInstruction) l2m;
return factory().actions().popMpls(EthType.of(popHeaderInstructions.ethernetType().toShort()));
case MPLS_LABEL:
ModMplsLabelInstruction mplsLabel = (ModMplsLabelInstruction) l2m;
oxm = factory().oxms().mplsLabel(U32.of(mplsLabel.label().toInt()));
break;
case MPLS_BOS:
ModMplsBosInstruction mplsBos = (ModMplsBosInstruction) l2m;
oxm = factory().oxms().mplsBos(mplsBos.mplsBos() ? OFBooleanValue.TRUE : OFBooleanValue.FALSE);
break;
case DEC_MPLS_TTL:
return factory().actions().decMplsTtl();
case VLAN_POP:
return factory().actions().popVlan();
case VLAN_PUSH:
ModVlanHeaderInstruction pushVlanInstruction = (ModVlanHeaderInstruction) l2m;
return factory().actions().pushVlan(EthType.of(pushVlanInstruction.ethernetType().toShort()));
case TUNNEL_ID:
ModTunnelIdInstruction tunnelId = (ModTunnelIdInstruction) l2m;
oxm = factory().oxms().tunnelId(U64.of(tunnelId.tunnelId()));
break;
default:
log.warn("Unimplemented action type {}.", l2m.subtype());
break;
}
if (oxm != null) {
return factory().actions().buildSetField().setField(oxm).build();
}
return null;
}
use of org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsHeaderInstruction in project onos by opennetworkinglab.
the class InstructionJsonMatcher method matchesSafely.
@Override
public boolean matchesSafely(JsonNode jsonInstruction, Description description) {
// check type
final JsonNode jsonTypeNode = jsonInstruction.get("type");
final String jsonType = jsonTypeNode.textValue();
final String type = instruction.type().name();
if (!jsonType.equals(type)) {
description.appendText("type was " + type);
return false;
}
if (instruction instanceof ModMplsHeaderInstruction) {
return matchModMplsHeaderInstruction(jsonInstruction, description);
} else if (instruction instanceof OutputInstruction) {
return matchOutputInstruction(jsonInstruction, description);
} else if (instruction instanceof GroupInstruction) {
return matchGroupInstruction(jsonInstruction, description);
} else if (instruction instanceof MeterInstruction) {
return matchMeterInstruction(jsonInstruction, description);
} else if (instruction instanceof SetQueueInstruction) {
return matchSetQueueInstruction(jsonInstruction, description);
} else if (instruction instanceof ModOchSignalInstruction) {
return matchModOchSingalInstruction(jsonInstruction, description);
} else if (instruction instanceof ModEtherInstruction) {
return matchModEtherInstruction(jsonInstruction, description);
} else if (instruction instanceof ModVlanIdInstruction) {
return matchModVlanIdInstruction(jsonInstruction, description);
} else if (instruction instanceof ModVlanPcpInstruction) {
return matchModVlanPcpInstruction(jsonInstruction, description);
} else if (instruction instanceof ModIPInstruction) {
return matchModIpInstruction(jsonInstruction, description);
} else if (instruction instanceof ModIPv6FlowLabelInstruction) {
return matchModIPv6FlowLabelInstruction(jsonInstruction, description);
} else if (instruction instanceof ModMplsLabelInstruction) {
return matchModMplsLabelInstruction(jsonInstruction, description);
} else if (instruction instanceof ModOduSignalIdInstruction) {
return matchModOduSingalIdInstruction(jsonInstruction, description);
} else if (instruction instanceof PiInstruction) {
return matchPiInstruction(jsonInstruction, description);
} else if (instruction instanceof NoActionInstruction) {
return true;
}
return false;
}
Aggregations