use of org.onosproject.net.flow.instructions.L2ModificationInstruction.L2SubType.VLAN_ID in project onos by opennetworkinglab.
the class NextObjectiveTranslator method nextVlan.
private void nextVlan(NextObjective obj, ObjectiveTranslation.Builder resultBuilder) throws FabricPipelinerException {
// We expect NextObjective treatments to contain one or two VLAN instructions.
// If two, this treatment should be mapped to an action for double-vlan push.
// In fabric.p4, mapping next IDs to VLAN IDs is done by a direct table (next_vlan),
// for this reason, we also make sure that all treatments in the NextObjective
// have exactly the same VLAN instructions, as they will be mapped to a single action
// Try to extract VLAN instructions in the treatment,
// later we check if we support multiple VLAN termination.
final List<List<ModVlanIdInstruction>> vlanInstructions = defaultNextTreatments(obj.nextTreatments(), false).stream().map(defaultNextTreatment -> l2Instructions(defaultNextTreatment.treatment(), VLAN_ID).stream().map(v -> (ModVlanIdInstruction) v).collect(Collectors.toList())).filter(l -> !l.isEmpty()).collect(Collectors.toList());
final VlanIdCriterion vlanIdCriterion = obj.meta() == null ? null : (VlanIdCriterion) criterion(obj.meta().criteria(), Criterion.Type.VLAN_VID);
final List<VlanId> vlanIdList;
if (vlanInstructions.isEmpty() && vlanIdCriterion == null) {
// No VLAN_ID to apply.
return;
}
if (!vlanInstructions.isEmpty()) {
// Give priority to what found in the instructions.
// Expect the same VLAN ID (or two VLAN IDs in the same order) for all instructions.
final Set<List<VlanId>> vlanIds = vlanInstructions.stream().map(l -> l.stream().map(ModVlanIdInstruction::vlanId).collect(Collectors.toList())).collect(Collectors.toSet());
if (obj.nextTreatments().size() != vlanInstructions.size() || vlanIds.size() != 1) {
throw new FabricPipelinerException("Inconsistent VLAN_ID instructions, cannot process " + "next_vlan rule. It is required that all " + "treatments have the same VLAN_ID instructions.");
}
vlanIdList = vlanIds.iterator().next();
} else {
// Use the value in meta.
// FIXME: there should be no need to generate a next_vlan rule for
// the value found in meta. Meta describes the fields that were
// expected to be matched in previous pipeline stages, i.e.
// existing packet fields. But, for some reason, if we remove this
// rule, traffic is not forwarded at spines. We might need to look
// at the way default VLANs are handled in fabric.p4.
vlanIdList = List.of(vlanIdCriterion.vlanId());
}
final TrafficSelector selector = nextIdSelector(obj.id());
final TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
vlanIdList.stream().forEach(vlanId -> treatmentBuilder.setVlanId(vlanId));
final TrafficTreatment treatment = treatmentBuilder.build();
resultBuilder.addFlowRule(flowRule(obj, FabricConstants.FABRIC_INGRESS_PRE_NEXT_NEXT_VLAN, selector, treatment));
}
use of org.onosproject.net.flow.instructions.L2ModificationInstruction.L2SubType.VLAN_ID in project onos by opennetworkinglab.
the class CorsaPipelineV39 method processNextTreatment.
@Override
protected CorsaTrafficTreatment processNextTreatment(TrafficTreatment treatment) {
TrafficTreatment.Builder tb = DefaultTrafficTreatment.builder();
treatment.immediate().stream().filter(i -> {
switch(i.type()) {
case L2MODIFICATION:
L2ModificationInstruction l2i = (L2ModificationInstruction) i;
return l2i.subtype() == VLAN_ID || l2i.subtype() == VLAN_POP || l2i.subtype() == ETH_DST || l2i.subtype() == ETH_SRC;
case OUTPUT:
return true;
default:
return false;
}
}).forEach(i -> tb.add(i));
TrafficTreatment t = tb.build();
boolean isPresentModVlanId = false;
boolean isPresentModEthSrc = false;
boolean isPresentModEthDst = false;
boolean isPresentOutpuPort = false;
for (Instruction instruction : t.immediate()) {
switch(instruction.type()) {
case L2MODIFICATION:
L2ModificationInstruction l2i = (L2ModificationInstruction) instruction;
if (l2i instanceof L2ModificationInstruction.ModVlanIdInstruction) {
isPresentModVlanId = true;
}
if (l2i instanceof L2ModificationInstruction.ModEtherInstruction) {
L2ModificationInstruction.L2SubType subType = l2i.subtype();
if (subType.equals(L2ModificationInstruction.L2SubType.ETH_SRC)) {
isPresentModEthSrc = true;
} else if (subType.equals(L2ModificationInstruction.L2SubType.ETH_DST)) {
isPresentModEthDst = true;
}
}
break;
case OUTPUT:
isPresentOutpuPort = true;
break;
default:
}
}
CorsaTrafficTreatmentType type = CorsaTrafficTreatmentType.ACTIONS;
/**
* These are the allowed groups for CorsaPipelinev39
*/
if (isPresentModVlanId && isPresentModEthSrc && isPresentModEthDst && isPresentOutpuPort) {
type = CorsaTrafficTreatmentType.GROUP;
} else if ((!isPresentModVlanId && isPresentModEthSrc && isPresentModEthDst && isPresentOutpuPort) || (!isPresentModVlanId && !isPresentModEthSrc && isPresentModEthDst && isPresentOutpuPort) || (!isPresentModVlanId && !isPresentModEthSrc && !isPresentModEthDst && isPresentOutpuPort)) {
type = CorsaTrafficTreatmentType.GROUP;
TrafficTreatment.Builder tb2 = DefaultTrafficTreatment.builder(t);
tb2.add(Instructions.popVlan());
t = tb2.build();
}
CorsaTrafficTreatment corsaTreatment = new CorsaTrafficTreatment(type, t);
return corsaTreatment;
}
use of org.onosproject.net.flow.instructions.L2ModificationInstruction.L2SubType.VLAN_ID in project fabric-tna by stratum.
the class NextObjectiveTranslator method nextVlan.
private void nextVlan(NextObjective obj, ObjectiveTranslation.Builder resultBuilder) throws FabricPipelinerException {
// We expect NextObjective treatments to contain one or two VLAN instructions.
// If two, this treatment should be mapped to an action for double-vlan push.
// In fabric.p4, mapping next IDs to VLAN IDs is done by a direct table (next_vlan),
// for this reason, we also make sure that all treatments in the NextObjective
// have exactly the same VLAN instructions, as they will be mapped to a single action
// Try to extract VLAN instructions in the treatment,
// later we check if we support multiple VLAN termination.
final List<List<ModVlanIdInstruction>> vlanInstructions = defaultNextTreatments(obj.nextTreatments(), false).stream().map(defaultNextTreatment -> l2Instructions(defaultNextTreatment.treatment(), VLAN_ID).stream().map(v -> (ModVlanIdInstruction) v).collect(Collectors.toList())).filter(l -> !l.isEmpty()).collect(Collectors.toList());
final VlanIdCriterion vlanIdCriterion = obj.meta() == null ? null : (VlanIdCriterion) criterion(obj.meta().criteria(), Criterion.Type.VLAN_VID);
final List<VlanId> vlanIdList;
if (vlanInstructions.isEmpty() && vlanIdCriterion == null) {
// No VLAN_ID to apply.
return;
}
if (!vlanInstructions.isEmpty()) {
// Give priority to what found in the instructions.
// Expect the same VLAN ID (or two VLAN IDs in the same order) for all instructions.
final Set<List<VlanId>> vlanIds = vlanInstructions.stream().map(l -> l.stream().map(ModVlanIdInstruction::vlanId).collect(Collectors.toList())).collect(Collectors.toSet());
if (obj.nextTreatments().size() != vlanInstructions.size() || vlanIds.size() != 1) {
throw new FabricPipelinerException("Inconsistent VLAN_ID instructions, cannot process " + "next_vlan rule. It is required that all " + "treatments have the same VLAN_ID instructions.");
}
vlanIdList = vlanIds.iterator().next();
} else {
// Use the value in meta.
// FIXME: there should be no need to generate a next_vlan rule for
// the value found in meta. Meta describes the fields that were
// expected to be matched in previous pipeline stages, i.e.
// existing packet fields. But, for some reason, if we remove this
// rule, traffic is not forwarded at spines. We might need to look
// at the way default VLANs are handled in fabric.p4.
vlanIdList = List.of(vlanIdCriterion.vlanId());
}
final TrafficSelector selector = nextIdSelector(obj.id());
final TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
vlanIdList.forEach(treatmentBuilder::setVlanId);
final TrafficTreatment treatment = treatmentBuilder.build();
resultBuilder.addFlowRule(flowRule(obj, P4InfoConstants.FABRIC_INGRESS_PRE_NEXT_NEXT_VLAN, selector, treatment));
}
Aggregations