Search in sources :

Example 1 with ModVlanIdInstruction

use of org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction in project onos by opennetworkinglab.

the class InstructionJsonMatcher method matchModVlanIdInstruction.

/**
 * Matches the contents of a mod vlan id instruction.
 *
 * @param instructionJson JSON instruction to match
 * @param description Description object used for recording errors
 * @return true if contents match, false otherwise
 */
private boolean matchModVlanIdInstruction(JsonNode instructionJson, Description description) {
    ModVlanIdInstruction instructionToMatch = (ModVlanIdInstruction) 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 short jsonVlanId = instructionJson.get("vlanId").shortValue();
    final short vlanId = instructionToMatch.vlanId().toShort();
    if (jsonVlanId != vlanId) {
        description.appendText("vlan id was " + jsonVlanId);
        return false;
    }
    return true;
}
Also used : ModVlanIdInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction) HexString(org.onlab.util.HexString)

Example 2 with ModVlanIdInstruction

use of org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction in project onos by opennetworkinglab.

the class OfdpaPipelineTraceable method apply.

@Override
public PipelineTraceableOutput apply(PipelineTraceableInput input) {
    PipelineTraceableOutput.Builder outputBuilder = PipelineTraceableOutput.builder();
    log.debug("Current packet {} - applying flow tables", input.ingressPacket());
    List<FlowEntry> outputFlows = new ArrayList<>();
    List<Instruction> deferredInstructions = new ArrayList<>();
    PipelineTraceableHitChain currentHitChain = PipelineTraceableHitChain.emptyHitChain();
    TrafficSelector currentPacket = DefaultTrafficSelector.builder(input.ingressPacket().packet()).build();
    // Init step - find out the first table
    int initialTableId = -1;
    FlowEntry nextTableIdEntry = findNextTableIdEntry(initialTableId, input.flows());
    if (nextTableIdEntry == null) {
        currentHitChain.setEgressPacket(new PipelineTraceablePacket(currentPacket));
        currentHitChain.dropped();
        return outputBuilder.appendToLog("No flow rules for device " + deviceId + ". Aborting").noFlows().addHitChain(currentHitChain).build();
    }
    // Iterates over the flow tables until the end of the pipeline
    TableId tableId = nextTableIdEntry.table();
    FlowEntry flowEntry;
    boolean lastTable = false;
    while (!lastTable) {
        log.debug("Searching a Flow Entry on table {} for packet {}", tableId, currentPacket);
        // Gets the rule that matches the incoming packet
        flowEntry = matchHighestPriority(currentPacket, tableId, input.flows());
        log.debug("Found Flow Entry {}", flowEntry);
        // If the flow entry on a table is null and we are on hardware we treat as table miss, with few exceptions
        if (flowEntry == null && isHardwareSwitch()) {
            log.debug("Ofdpa Hw setup, no flow rule means table miss");
            if (((IndexTableId) tableId).id() == MPLS_L3_TYPE_TABLE) {
                // Apparently a miss but Table 27 on OFDPA is a fixed table
                currentPacket = handleOfdpa27FixedTable(input.ingressPacket().packet(), currentPacket);
                // The nextTable should be ACL
                tableId = IndexTableId.of(ACL_TABLE - 1);
            }
            // Finding next table to go In case of miss
            nextTableIdEntry = findNextTableIdEntry(((IndexTableId) tableId).id(), input.flows());
            log.debug("Next table id entry {}", nextTableIdEntry);
            // (another possibility is max tableId)
            if (nextTableIdEntry == null && currentHitChain.hitChain().size() == 0) {
                currentHitChain.setEgressPacket(new PipelineTraceablePacket(currentPacket));
                currentHitChain.dropped();
                return outputBuilder.appendToLog("No flow rules for device " + deviceId + ". Aborting").noFlows().addHitChain(currentHitChain).build();
            } else if (nextTableIdEntry == null) {
                // Means that no more flow rules are present
                lastTable = true;
            } else if (((IndexTableId) tableId).id() == TMAC_TABLE) {
                // If the table is 20 OFDPA skips to table 50
                log.debug("A miss on Table 20 on OFDPA means that we skip directly to table 50");
                tableId = IndexTableId.of(BRIDGING_TABLE);
            } else if (((IndexTableId) tableId).id() == MULTICAST_ROUTING_TABLE) {
                // If the table is 40 OFDPA skips to table 60
                log.debug("A miss on Table 40 on OFDPA means that we skip directly to table 60");
                tableId = IndexTableId.of(ACL_TABLE);
            } else {
                tableId = nextTableIdEntry.table();
            }
        } else if (flowEntry == null) {
            currentHitChain.setEgressPacket(new PipelineTraceablePacket(currentPacket));
            currentHitChain.dropped();
            return outputBuilder.appendToLog("Packet has no match on table " + tableId + " in device " + deviceId + ". Dropping").noFlows().addHitChain(currentHitChain).build();
        } else {
            // If the table has a transition
            if (flowEntry.treatment().tableTransition() != null) {
                // Updates the next table we transitions to
                tableId = IndexTableId.of(flowEntry.treatment().tableTransition().tableId());
                log.debug("Flow Entry has transition to table Id {}", tableId);
                currentHitChain.addDataPlaneEntity(new DataPlaneEntity(flowEntry));
            } else {
                // Table has no transition so it means that it's an output rule if on the last table
                log.debug("Flow Entry has no transition to table, treating as last rule {}", flowEntry);
                currentHitChain.addDataPlaneEntity(new DataPlaneEntity(flowEntry));
                outputFlows.add(flowEntry);
                lastTable = true;
            }
            // Updates the packet according to the immediate actions of this flow rule.
            currentPacket = updatePacket(currentPacket, flowEntry.treatment().immediate()).build();
            // Saves the deferred rules for later maintaining the order
            deferredInstructions.addAll(flowEntry.treatment().deferred());
            // If the flow requires to clear deferred actions we do so for all the ones we encountered.
            if (flowEntry.treatment().clearedDeferred()) {
                deferredInstructions.clear();
            }
            // On table 10 OFDPA needs two rules to apply the vlan if none and then to transition to the next table.
            if (shouldMatchSecondVlanFlow(flowEntry)) {
                // Let's get the packet vlanId instruction
                VlanIdCriterion packetVlanIdCriterion = (VlanIdCriterion) currentPacket.getCriterion(Criterion.Type.VLAN_VID);
                // Let's get the flow entry vlan mod instructions
                ModVlanIdInstruction entryModVlanIdInstruction = (ModVlanIdInstruction) flowEntry.treatment().immediate().stream().filter(instruction -> instruction instanceof ModVlanIdInstruction).findFirst().orElse(null);
                // is a flow rule that matches on same criteria and with updated vlanId
                if (entryModVlanIdInstruction != null) {
                    FlowEntry secondVlanFlow = getSecondFlowEntryOnTable10(currentPacket, packetVlanIdCriterion, entryModVlanIdInstruction, input.flows());
                    // We found the flow that we expected
                    if (secondVlanFlow != null) {
                        currentHitChain.addDataPlaneEntity(new DataPlaneEntity(secondVlanFlow));
                    } else {
                        currentHitChain.setEgressPacket(new PipelineTraceablePacket(currentPacket));
                        currentHitChain.dropped();
                        return outputBuilder.appendToLog("Missing forwarding rule for tagged" + " packet on " + deviceId).noFlows().addHitChain(currentHitChain).build();
                    }
                }
            }
        }
    }
    // Creating a modifiable builder for the egress packet
    TrafficSelector.Builder egressPacket = DefaultTrafficSelector.builder(currentPacket);
    log.debug("Current packet {} - applying output flows", currentPacket);
    // Handling output flows which basically means handling output to controller.
    // OVS and OFDPA have both immediate -> OUTPUT:CONTROLLER. Theoretically there is no
    // need to reflect the updates performed on the packets and on the chain.
    List<PortNumber> outputPorts = new ArrayList<>();
    handleOutputFlows(currentPacket, outputFlows, egressPacket, outputPorts, currentHitChain, outputBuilder, input.ingressPacket().packet());
    // Immediate instructions
    log.debug("Current packet {} - applying immediate instructions", currentPacket);
    // Handling immediate instructions which basically means handling output to controller.
    // OVS has immediate -> group -> OUTPUT:CONTROLLER.
    List<DataPlaneEntity> entries = ImmutableList.copyOf(currentHitChain.hitChain());
    // Go to the next step - using a copy of the egress packet and of the hit chain
    PipelineTraceableHitChain newHitChain = PipelineTraceableHitChain.emptyHitChain();
    currentHitChain.hitChain().forEach(newHitChain::addDataPlaneEntity);
    TrafficSelector.Builder newEgressPacket = DefaultTrafficSelector.builder(egressPacket.build());
    for (DataPlaneEntity entry : entries) {
        flowEntry = entry.getFlowEntry();
        if (flowEntry != null) {
            getGroupsFromInstructions(input.groups(), flowEntry.treatment().immediate(), newEgressPacket, outputPorts, newHitChain, outputBuilder, input, false);
        }
    }
    // Deferred instructions
    log.debug("Current packet {} - applying deferred instructions", egressPacket.build());
    // egress packet and of the hit chain. This is the last step.
    if (deferredInstructions.size() > 0) {
        handleDeferredActions(egressPacket.build(), input.groups(), deferredInstructions, outputPorts, currentHitChain, outputBuilder, input);
    }
    // Let's store the partial hit chain and set a message
    if (outputPorts.isEmpty()) {
        currentHitChain.setEgressPacket(new PipelineTraceablePacket(egressPacket.build()));
        currentHitChain.dropped();
        outputBuilder.appendToLog("Packet has no output in device " + deviceId + ". Dropping").dropped().addHitChain(currentHitChain);
    }
    // Done!
    return outputBuilder.build();
}
Also used : IndexTableId(org.onosproject.net.flow.IndexTableId) TableId(org.onosproject.net.flow.TableId) IndexTableId(org.onosproject.net.flow.IndexTableId) ArrayList(java.util.ArrayList) L2ModificationInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction) OutputInstruction(org.onosproject.net.flow.instructions.Instructions.OutputInstruction) ModVlanIdInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction) Instruction(org.onosproject.net.flow.instructions.Instruction) ConnectPoint(org.onosproject.net.ConnectPoint) DataPlaneEntity(org.onosproject.net.DataPlaneEntity) ModVlanIdInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction) TrafficSelector(org.onosproject.net.flow.TrafficSelector) DefaultTrafficSelector(org.onosproject.net.flow.DefaultTrafficSelector) PipelineTraceableOutput(org.onosproject.net.PipelineTraceableOutput) PipelineTraceableHitChain(org.onosproject.net.PipelineTraceableHitChain) PortNumber(org.onosproject.net.PortNumber) FlowEntry(org.onosproject.net.flow.FlowEntry) PipelineTraceablePacket(org.onosproject.net.PipelineTraceablePacket) VlanIdCriterion(org.onosproject.net.flow.criteria.VlanIdCriterion)

Example 3 with ModVlanIdInstruction

use of org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction in project onos by opennetworkinglab.

the class FlowModBuilderVer10 method buildL2Modification.

private OFAction buildL2Modification(Instruction i) {
    L2ModificationInstruction l2m = (L2ModificationInstruction) i;
    ModEtherInstruction eth;
    switch(l2m.subtype()) {
        case ETH_DST:
            eth = (ModEtherInstruction) l2m;
            return factory().actions().setDlDst(MacAddress.of(eth.mac().toLong()));
        case ETH_SRC:
            eth = (ModEtherInstruction) l2m;
            return factory().actions().setDlSrc(MacAddress.of(eth.mac().toLong()));
        case VLAN_ID:
            ModVlanIdInstruction vlanId = (ModVlanIdInstruction) l2m;
            return factory().actions().setVlanVid(VlanVid.ofVlan(vlanId.vlanId().toShort()));
        case VLAN_PCP:
            ModVlanPcpInstruction vlanPcp = (ModVlanPcpInstruction) l2m;
            return factory().actions().setVlanPcp(VlanPcp.of(vlanPcp.vlanPcp()));
        case VLAN_POP:
            return factory().actions().stripVlan();
        case VLAN_PUSH:
            return null;
        default:
            log.warn("Unimplemented action type {}.", l2m.subtype());
            break;
    }
    return null;
}
Also used : ModVlanIdInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction) L2ModificationInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction) ModEtherInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction) ModVlanPcpInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction)

Example 4 with ModVlanIdInstruction

use of org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction 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;
}
Also used : OutputInstruction(org.onosproject.net.flow.instructions.Instructions.OutputInstruction) ModOchSignalInstruction(org.onosproject.net.flow.instructions.L0ModificationInstruction.ModOchSignalInstruction) PiInstruction(org.onosproject.net.flow.instructions.PiInstruction) JsonNode(com.fasterxml.jackson.databind.JsonNode) HexString(org.onlab.util.HexString) ModEtherInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction) ModMplsHeaderInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsHeaderInstruction) ModIPInstruction(org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPInstruction) ModOduSignalIdInstruction(org.onosproject.net.flow.instructions.L1ModificationInstruction.ModOduSignalIdInstruction) SetQueueInstruction(org.onosproject.net.flow.instructions.Instructions.SetQueueInstruction) ModMplsLabelInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsLabelInstruction) ModVlanIdInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction) NoActionInstruction(org.onosproject.net.flow.instructions.Instructions.NoActionInstruction) MeterInstruction(org.onosproject.net.flow.instructions.Instructions.MeterInstruction) ModIPv6FlowLabelInstruction(org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPv6FlowLabelInstruction) GroupInstruction(org.onosproject.net.flow.instructions.Instructions.GroupInstruction) ModVlanPcpInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction)

Example 5 with ModVlanIdInstruction

use of org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction in project onos by opennetworkinglab.

the class LinkCollectionCompiler method updateBuilder.

/**
 * Update the selector builder using a L2 instruction.
 *
 * @param builder the builder to update
 * @param l2instruction the l2 instruction to use
 */
private void updateBuilder(TrafficSelector.Builder builder, L2ModificationInstruction l2instruction) {
    switch(l2instruction.subtype()) {
        case ETH_SRC:
        case ETH_DST:
            ModEtherInstruction ethInstr = (ModEtherInstruction) l2instruction;
            switch(ethInstr.subtype()) {
                case ETH_SRC:
                    builder.matchEthSrc(ethInstr.mac());
                    break;
                case ETH_DST:
                    builder.matchEthDst(ethInstr.mac());
                    break;
                default:
                    throw new IntentCompilationException(UNSUPPORTED_ETH_SUBTYPE);
            }
            break;
        case VLAN_ID:
            ModVlanIdInstruction vlanIdInstr = (ModVlanIdInstruction) l2instruction;
            builder.matchVlanId(vlanIdInstr.vlanId());
            break;
        case VLAN_PUSH:
            // FIXME
            break;
        case VLAN_POP:
            // TODO how do we handle dropped label? remove the selector?
            throw new IntentCompilationException(UNSUPPORTED_POP_ACTION);
        case VLAN_PCP:
            ModVlanPcpInstruction vlanPcpInstruction = (ModVlanPcpInstruction) l2instruction;
            builder.matchVlanPcp(vlanPcpInstruction.vlanPcp());
            break;
        case MPLS_LABEL:
        case MPLS_PUSH:
            // FIXME
            ModMplsLabelInstruction mplsInstr = (ModMplsLabelInstruction) l2instruction;
            builder.matchMplsLabel(mplsInstr.label());
            break;
        case MPLS_POP:
            // TODO how do we handle dropped label? remove the selector?
            throw new IntentCompilationException(UNSUPPORTED_POP_ACTION);
        case DEC_MPLS_TTL:
            // no-op
            break;
        case MPLS_BOS:
            ModMplsBosInstruction mplsBosInstr = (ModMplsBosInstruction) l2instruction;
            builder.matchMplsBos(mplsBosInstr.mplsBos());
            break;
        case TUNNEL_ID:
            ModTunnelIdInstruction tunInstr = (ModTunnelIdInstruction) l2instruction;
            builder.matchTunnelId(tunInstr.tunnelId());
            break;
        default:
            throw new IntentCompilationException(UNSUPPORTED_L2);
    }
}
Also used : ModMplsLabelInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsLabelInstruction) ModTunnelIdInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction.ModTunnelIdInstruction) ModMplsBosInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsBosInstruction) ModVlanIdInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction) ModEtherInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction) IntentCompilationException(org.onosproject.net.intent.IntentCompilationException) ModVlanPcpInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction)

Aggregations

ModVlanIdInstruction (org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction)9 L2ModificationInstruction (org.onosproject.net.flow.instructions.L2ModificationInstruction)5 VlanIdCriterion (org.onosproject.net.flow.criteria.VlanIdCriterion)4 Instruction (org.onosproject.net.flow.instructions.Instruction)4 OutputInstruction (org.onosproject.net.flow.instructions.Instructions.OutputInstruction)4 ModEtherInstruction (org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction)4 ModMplsLabelInstruction (org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsLabelInstruction)4 ModVlanPcpInstruction (org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction)4 VlanId (org.onlab.packet.VlanId)3 PortNumber (org.onosproject.net.PortNumber)3 DefaultTrafficSelector (org.onosproject.net.flow.DefaultTrafficSelector)3 TrafficSelector (org.onosproject.net.flow.TrafficSelector)3 Criterion (org.onosproject.net.flow.criteria.Criterion)3 Lists (com.google.common.collect.Lists)2 ArrayList (java.util.ArrayList)2 List (java.util.List)2 Set (java.util.Set)2 Collectors (java.util.stream.Collectors)2 HexString (org.onlab.util.HexString)2 DeviceId (org.onosproject.net.DeviceId)2