Search in sources :

Example 1 with L3ModificationInstruction

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

the class FlowRuleCodecTest method decodeInstructionsFlowTest.

/**
 * Checks that a rule with one of each instruction type decodes properly.
 *
 * @throws IOException if the resource cannot be processed
 */
@Test
public void decodeInstructionsFlowTest() throws Exception {
    FlowRule rule = getRule("instructions-flow.json");
    checkCommonData(rule);
    rule.treatment().allInstructions().forEach(instruction -> {
        String subType;
        if (instruction.type() == Instruction.Type.L0MODIFICATION) {
            subType = ((L0ModificationInstruction) instruction).subtype().name();
        } else if (instruction.type() == Instruction.Type.L2MODIFICATION) {
            subType = ((L2ModificationInstruction) instruction).subtype().name();
        } else if (instruction.type() == Instruction.Type.L3MODIFICATION) {
            subType = ((L3ModificationInstruction) instruction).subtype().name();
        } else if (instruction.type() == Instruction.Type.L4MODIFICATION) {
            subType = ((L4ModificationInstruction) instruction).subtype().name();
        } else {
            subType = "";
        }
        instructions.put(instruction.type().name() + "/" + subType, instruction);
    });
    assertThat(rule.treatment().allInstructions().size(), is(23));
    Instruction instruction;
    instruction = getInstruction(Instruction.Type.OUTPUT, "");
    assertThat(instruction.type(), is(Instruction.Type.OUTPUT));
    assertThat(((Instructions.OutputInstruction) instruction).port(), is(PortNumber.CONTROLLER));
    instruction = getInstruction(Instruction.Type.L2MODIFICATION, L2ModificationInstruction.L2SubType.ETH_SRC.name());
    assertThat(instruction.type(), is(Instruction.Type.L2MODIFICATION));
    assertThat(((L2ModificationInstruction.ModEtherInstruction) instruction).mac(), is(MacAddress.valueOf("12:34:56:78:90:12")));
    instruction = getInstruction(Instruction.Type.L2MODIFICATION, L2ModificationInstruction.L2SubType.ETH_DST.name());
    assertThat(instruction.type(), is(Instruction.Type.L2MODIFICATION));
    assertThat(((L2ModificationInstruction.ModEtherInstruction) instruction).mac(), is(MacAddress.valueOf("98:76:54:32:01:00")));
    instruction = getInstruction(Instruction.Type.L2MODIFICATION, L2ModificationInstruction.L2SubType.VLAN_ID.name());
    assertThat(instruction.type(), is(Instruction.Type.L2MODIFICATION));
    assertThat(((L2ModificationInstruction.ModVlanIdInstruction) instruction).vlanId().toShort(), is((short) 22));
    instruction = getInstruction(Instruction.Type.L2MODIFICATION, L2ModificationInstruction.L2SubType.VLAN_PCP.name());
    assertThat(instruction.type(), is(Instruction.Type.L2MODIFICATION));
    assertThat(((L2ModificationInstruction.ModVlanPcpInstruction) instruction).vlanPcp(), is((byte) 1));
    instruction = getInstruction(Instruction.Type.L2MODIFICATION, L2ModificationInstruction.L2SubType.MPLS_LABEL.name());
    assertThat(instruction.type(), is(Instruction.Type.L2MODIFICATION));
    assertThat(((L2ModificationInstruction.ModMplsLabelInstruction) instruction).label().toInt(), is(MplsLabel.MAX_MPLS));
    instruction = getInstruction(Instruction.Type.L2MODIFICATION, L2ModificationInstruction.L2SubType.MPLS_PUSH.name());
    assertThat(instruction.type(), is(Instruction.Type.L2MODIFICATION));
    assertThat(((L2ModificationInstruction.ModMplsHeaderInstruction) instruction).ethernetType().toShort(), is(Ethernet.MPLS_UNICAST));
    instruction = getInstruction(Instruction.Type.L2MODIFICATION, L2ModificationInstruction.L2SubType.MPLS_POP.name());
    assertThat(instruction.type(), is(Instruction.Type.L2MODIFICATION));
    assertThat(((L2ModificationInstruction.ModMplsHeaderInstruction) instruction).ethernetType().toShort(), is(Ethernet.MPLS_UNICAST));
    instruction = getInstruction(Instruction.Type.L2MODIFICATION, L2ModificationInstruction.L2SubType.DEC_MPLS_TTL.name());
    assertThat(instruction.type(), is(Instruction.Type.L2MODIFICATION));
    assertThat(instruction, instanceOf(L2ModificationInstruction.ModMplsTtlInstruction.class));
    instruction = getInstruction(Instruction.Type.L2MODIFICATION, L2ModificationInstruction.L2SubType.VLAN_POP.name());
    assertThat(instruction.type(), is(Instruction.Type.L2MODIFICATION));
    assertThat(instruction, instanceOf(L2ModificationInstruction.ModVlanHeaderInstruction.class));
    instruction = getInstruction(Instruction.Type.L2MODIFICATION, L2ModificationInstruction.L2SubType.VLAN_PUSH.name());
    assertThat(instruction.type(), is(Instruction.Type.L2MODIFICATION));
    assertThat(instruction, instanceOf(L2ModificationInstruction.ModVlanHeaderInstruction.class));
    instruction = getInstruction(Instruction.Type.L2MODIFICATION, L2ModificationInstruction.L2SubType.TUNNEL_ID.name());
    assertThat(instruction.type(), is(Instruction.Type.L2MODIFICATION));
    assertThat(((L2ModificationInstruction.ModTunnelIdInstruction) instruction).tunnelId(), is(100L));
    instruction = getInstruction(Instruction.Type.L3MODIFICATION, L3ModificationInstruction.L3SubType.IPV4_SRC.name());
    assertThat(instruction.type(), is(Instruction.Type.L3MODIFICATION));
    assertThat(((L3ModificationInstruction.ModIPInstruction) instruction).ip(), is(IpAddress.valueOf("1.2.3.4")));
    instruction = getInstruction(Instruction.Type.L3MODIFICATION, L3ModificationInstruction.L3SubType.IPV4_DST.name());
    assertThat(instruction.type(), is(Instruction.Type.L3MODIFICATION));
    assertThat(((L3ModificationInstruction.ModIPInstruction) instruction).ip(), is(IpAddress.valueOf("1.2.3.3")));
    instruction = getInstruction(Instruction.Type.L3MODIFICATION, L3ModificationInstruction.L3SubType.IPV6_SRC.name());
    assertThat(instruction.type(), is(Instruction.Type.L3MODIFICATION));
    assertThat(((L3ModificationInstruction.ModIPInstruction) instruction).ip(), is(IpAddress.valueOf("1.2.3.2")));
    instruction = getInstruction(Instruction.Type.L3MODIFICATION, L3ModificationInstruction.L3SubType.IPV6_DST.name());
    assertThat(instruction.type(), is(Instruction.Type.L3MODIFICATION));
    assertThat(((L3ModificationInstruction.ModIPInstruction) instruction).ip(), is(IpAddress.valueOf("1.2.3.1")));
    instruction = getInstruction(Instruction.Type.L3MODIFICATION, L3ModificationInstruction.L3SubType.IPV6_FLABEL.name());
    assertThat(instruction.type(), is(Instruction.Type.L3MODIFICATION));
    assertThat(((L3ModificationInstruction.ModIPv6FlowLabelInstruction) instruction).flowLabel(), is(8));
    instruction = getInstruction(Instruction.Type.L0MODIFICATION, L0ModificationInstruction.L0SubType.OCH.name());
    assertThat(instruction.type(), is(Instruction.Type.L0MODIFICATION));
    L0ModificationInstruction.ModOchSignalInstruction och = (L0ModificationInstruction.ModOchSignalInstruction) instruction;
    assertThat(och.lambda().spacingMultiplier(), is(4));
    assertThat(och.lambda().slotGranularity(), is(8));
    assertThat(och.lambda().gridType(), is(GridType.DWDM));
    assertThat(och.lambda().channelSpacing(), is(ChannelSpacing.CHL_100GHZ));
    instruction = getInstruction(Instruction.Type.L4MODIFICATION, L4ModificationInstruction.L4SubType.TCP_DST.name());
    assertThat(instruction.type(), is(Instruction.Type.L4MODIFICATION));
    assertThat(((L4ModificationInstruction.ModTransportPortInstruction) instruction).port().toInt(), is(40001));
    instruction = getInstruction(Instruction.Type.L4MODIFICATION, L4ModificationInstruction.L4SubType.TCP_SRC.name());
    assertThat(instruction.type(), is(Instruction.Type.L4MODIFICATION));
    assertThat(((L4ModificationInstruction.ModTransportPortInstruction) instruction).port().toInt(), is(40002));
    instruction = getInstruction(Instruction.Type.L4MODIFICATION, L4ModificationInstruction.L4SubType.UDP_DST.name());
    assertThat(instruction.type(), is(Instruction.Type.L4MODIFICATION));
    assertThat(((L4ModificationInstruction.ModTransportPortInstruction) instruction).port().toInt(), is(40003));
    instruction = getInstruction(Instruction.Type.L4MODIFICATION, L4ModificationInstruction.L4SubType.UDP_SRC.name());
    assertThat(instruction.type(), is(Instruction.Type.L4MODIFICATION));
    assertThat(((L4ModificationInstruction.ModTransportPortInstruction) instruction).port().toInt(), is(40004));
}
Also used : L3ModificationInstruction(org.onosproject.net.flow.instructions.L3ModificationInstruction) Instructions(org.onosproject.net.flow.instructions.Instructions) L2ModificationInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction) L2ModificationInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction) L3ModificationInstruction(org.onosproject.net.flow.instructions.L3ModificationInstruction) L4ModificationInstruction(org.onosproject.net.flow.instructions.L4ModificationInstruction) L0ModificationInstruction(org.onosproject.net.flow.instructions.L0ModificationInstruction) Instruction(org.onosproject.net.flow.instructions.Instruction) L0ModificationInstruction(org.onosproject.net.flow.instructions.L0ModificationInstruction) DefaultFlowRule(org.onosproject.net.flow.DefaultFlowRule) FlowRule(org.onosproject.net.flow.FlowRule) Test(org.junit.Test)

Example 2 with L3ModificationInstruction

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

the class Ofdpa3GroupHandler method processPwNextObjective.

@Override
protected void processPwNextObjective(NextObjective nextObjective) {
    log.info("Started deploying nextObjective id={} for pseudowire", nextObjective.id());
    TrafficTreatment treatment = nextObjective.next().iterator().next();
    Deque<GroupKey> gkeyChain = new ArrayDeque<>();
    GroupChainElem groupChainElem;
    GroupKey groupKey;
    GroupDescription groupDescription;
    // Now we separate the mpls actions from the l2/l3 actions
    TrafficTreatment.Builder l2L3Treatment = DefaultTrafficTreatment.builder();
    TrafficTreatment.Builder mplsTreatment = DefaultTrafficTreatment.builder();
    createL2L3AndMplsTreatments(treatment, l2L3Treatment, mplsTreatment);
    // We create the chain from mpls intf group to
    // l2 intf group.
    GroupInfo groupInfo = createL2L3ChainInternal(l2L3Treatment.build(), nextObjective.id(), nextObjective.appId(), true, nextObjective.meta(), false);
    if (groupInfo == null) {
        log.error("Could not process nextObj={} in dev:{}", nextObjective.id(), deviceId);
        OfdpaPipelineUtility.fail(nextObjective, ObjectiveError.GROUPINSTALLATIONFAILED);
        return;
    }
    // We update the chain with the last two groups;
    gkeyChain.addFirst(groupInfo.innerMostGroupDesc().appCookie());
    gkeyChain.addFirst(groupInfo.nextGroupDesc().appCookie());
    // We retrieve also all mpls instructions.
    List<List<Instruction>> mplsInstructionSets = Lists.newArrayList();
    List<Instruction> mplsInstructionSet = Lists.newArrayList();
    L3ModificationInstruction l3Ins;
    for (Instruction ins : treatment.allInstructions()) {
        // Each mpls instruction set is delimited by a
        // copy ttl outward action.
        mplsInstructionSet.add(ins);
        if (ins.type() == Instruction.Type.L3MODIFICATION) {
            l3Ins = (L3ModificationInstruction) ins;
            if (l3Ins.subtype() == TTL_OUT) {
                mplsInstructionSets.add(mplsInstructionSet);
                mplsInstructionSet = Lists.newArrayList();
            }
        }
    }
    if (mplsInstructionSets.size() > MAX_DEPTH_UNPROTECTED_PW) {
        log.error("Next Objective for pseudo wire should have at " + "most {} mpls instruction sets. Next Objective Id:{}", MAX_DEPTH_UNPROTECTED_PW, nextObjective.id());
        OfdpaPipelineUtility.fail(nextObjective, ObjectiveError.BADPARAMS);
        return;
    }
    log.debug("Size of mpls instructions is {}.", mplsInstructionSets.size());
    log.debug("mpls instructions sets are {}.", mplsInstructionSets);
    int nextGid = groupInfo.nextGroupDesc().givenGroupId();
    int index;
    // this is for inter-co pws
    if (mplsInstructionSets.size() == MAX_DEPTH_UNPROTECTED_PW) {
        log.debug("Creating inter-co pw mpls chains with nextid {}", nextObjective.id());
        // We deal with the label 2 group.
        index = getNextAvailableIndex();
        groupDescription = createMplsTunnelLabelGroup(nextGid, OfdpaMplsGroupSubType.MPLS_TUNNEL_LABEL_2, index, mplsInstructionSets.get(2), nextObjective.appId());
        groupKey = new DefaultGroupKey(Ofdpa2Pipeline.appKryo.serialize(index));
        // We update the chain.
        groupChainElem = new GroupChainElem(groupDescription, 1, false, deviceId);
        updatePendingGroups(groupInfo.nextGroupDesc().appCookie(), groupChainElem);
        gkeyChain.addFirst(groupKey);
        // We have to create tunnel label group and
        // l2 vpn group before to send the inner most
        // group. We update the nextGid.
        nextGid = groupDescription.givenGroupId();
        groupInfo = new GroupInfo(groupInfo.innerMostGroupDesc(), groupDescription);
        log.debug("Trying Label 2 Group: device:{} gid:{} gkey:{} nextId:{}", deviceId, Integer.toHexString(nextGid), groupKey, nextObjective.id());
    }
    // inside a single co
    if (mplsInstructionSets.size() == 2) {
        log.debug("Creating leaf-leaf pw mpls chains with nextid {}", nextObjective.id());
        // We deal with the label 1 group.
        index = getNextAvailableIndex();
        groupDescription = createMplsTunnelLabelGroup(nextGid, OfdpaMplsGroupSubType.MPLS_TUNNEL_LABEL_1, index, mplsInstructionSets.get(1), nextObjective.appId());
        groupKey = new DefaultGroupKey(Ofdpa2Pipeline.appKryo.serialize(index));
        groupChainElem = new GroupChainElem(groupDescription, 1, false, deviceId);
        updatePendingGroups(groupInfo.nextGroupDesc().appCookie(), groupChainElem);
        gkeyChain.addFirst(groupKey);
        // We have to create the l2 vpn group before
        // to send the inner most group.
        nextGid = groupDescription.givenGroupId();
        groupInfo = new GroupInfo(groupInfo.innerMostGroupDesc(), groupDescription);
        log.debug("Trying Label 1 Group: device:{} gid:{} gkey:{} nextId:{}", deviceId, Integer.toHexString(nextGid), groupKey, nextObjective.id());
        // Finally we create the l2 vpn group.
        index = getNextAvailableIndex();
        groupDescription = createMplsL2VpnGroup(nextGid, index, mplsInstructionSets.get(0), nextObjective.appId());
        groupKey = new DefaultGroupKey(Ofdpa2Pipeline.appKryo.serialize(index));
        groupChainElem = new GroupChainElem(groupDescription, 1, false, deviceId);
        updatePendingGroups(groupInfo.nextGroupDesc().appCookie(), groupChainElem);
        gkeyChain.addFirst(groupKey);
        OfdpaNextGroup ofdpaGrp = new OfdpaNextGroup(Collections.singletonList(gkeyChain), nextObjective);
        updatePendingNextObjective(groupKey, ofdpaGrp);
        log.debug("Trying L2 Vpn Group: device:{} gid:{} gkey:{} nextId:{}", deviceId, Integer.toHexString(nextGid), groupKey, nextObjective.id());
        // Finally we send the innermost group.
        log.debug("Sending innermost group {} in group chain on device {} ", Integer.toHexString(groupInfo.innerMostGroupDesc().givenGroupId()), deviceId);
        groupService.addGroup(groupInfo.innerMostGroupDesc());
    }
    // only one label is used
    if (mplsInstructionSets.size() == 1) {
        log.debug("Creating leaf-spine pw mpls chains with nextid {}", nextObjective.id());
        // Finally we create the l2 vpn group.
        index = getNextAvailableIndex();
        groupDescription = createMplsL2VpnGroup(nextGid, index, mplsInstructionSets.get(0), nextObjective.appId());
        groupKey = new DefaultGroupKey(Ofdpa2Pipeline.appKryo.serialize(index));
        groupChainElem = new GroupChainElem(groupDescription, 1, false, deviceId);
        updatePendingGroups(groupInfo.nextGroupDesc().appCookie(), groupChainElem);
        gkeyChain.addFirst(groupKey);
        OfdpaNextGroup ofdpaGrp = new OfdpaNextGroup(Collections.singletonList(gkeyChain), nextObjective);
        updatePendingNextObjective(groupKey, ofdpaGrp);
        log.debug("Trying L2 Vpn Group: device:{} gid:{} gkey:{} nextId:{}", deviceId, Integer.toHexString(nextGid), groupKey, nextObjective.id());
        // Finally we send the innermost group.
        log.debug("Sending innermost group {} in group chain on device {} ", Integer.toHexString(groupInfo.innerMostGroupDesc().givenGroupId()), deviceId);
        groupService.addGroup(groupInfo.innerMostGroupDesc());
    }
}
Also used : L3ModificationInstruction(org.onosproject.net.flow.instructions.L3ModificationInstruction) GroupKey(org.onosproject.net.group.GroupKey) DefaultGroupKey(org.onosproject.net.group.DefaultGroupKey) DefaultTrafficTreatment(org.onosproject.net.flow.DefaultTrafficTreatment) TrafficTreatment(org.onosproject.net.flow.TrafficTreatment) L2ModificationInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction) L3ModificationInstruction(org.onosproject.net.flow.instructions.L3ModificationInstruction) Instruction(org.onosproject.net.flow.instructions.Instruction) ArrayDeque(java.util.ArrayDeque) DefaultGroupDescription(org.onosproject.net.group.DefaultGroupDescription) GroupDescription(org.onosproject.net.group.GroupDescription) DefaultGroupKey(org.onosproject.net.group.DefaultGroupKey) List(java.util.List)

Example 3 with L3ModificationInstruction

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

the class OvsOfdpaPipeline method processEthTypeSpecific.

/*
     * Open vSwitch emulation allows MPLS ECMP.
     *
     * (non-Javadoc)
     * @see org.onosproject.driver.pipeline.OFDPA2Pipeline#processEthTypeSpecific
     */
@Override
protected Collection<FlowRule> processEthTypeSpecific(ForwardingObjective fwd) {
    if (isDoubleTagged(fwd)) {
        return processDoubleTaggedFwd(fwd);
    }
    TrafficSelector selector = fwd.selector();
    EthTypeCriterion ethType = (EthTypeCriterion) selector.getCriterion(Criterion.Type.ETH_TYPE);
    if ((ethType == null) || (ethType.ethType().toShort() != Ethernet.TYPE_IPV4) && (ethType.ethType().toShort() != Ethernet.MPLS_UNICAST) && (ethType.ethType().toShort() != Ethernet.TYPE_IPV6)) {
        log.warn("processSpecific: Unsupported forwarding objective criteria" + "ethType:{} in dev:{}", ethType, deviceId);
        fail(fwd, ObjectiveError.UNSUPPORTED);
        return Collections.emptySet();
    }
    boolean defaultRule = false;
    int forTableId;
    TrafficSelector.Builder filteredSelector = DefaultTrafficSelector.builder();
    TrafficSelector.Builder complementarySelector = DefaultTrafficSelector.builder();
    if (ethType.ethType().toShort() == Ethernet.TYPE_IPV4) {
        IpPrefix ipv4Dst = ((IPCriterion) selector.getCriterion(Criterion.Type.IPV4_DST)).ip();
        if (ipv4Dst.isMulticast()) {
            if (ipv4Dst.prefixLength() != 32) {
                log.warn("Multicast specific forwarding objective can only be /32");
                fail(fwd, ObjectiveError.BADPARAMS);
                return ImmutableSet.of();
            }
            VlanId assignedVlan = readVlanFromSelector(fwd.meta());
            if (assignedVlan == null) {
                log.warn("VLAN ID required by multicast specific fwd obj is missing. Abort.");
                fail(fwd, ObjectiveError.BADPARAMS);
                return ImmutableSet.of();
            }
            filteredSelector.matchVlanId(assignedVlan);
            filteredSelector.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(ipv4Dst);
            forTableId = MULTICAST_ROUTING_TABLE;
            log.debug("processing IPv4 multicast specific forwarding objective {} -> next:{}" + " in dev:{}", fwd.id(), fwd.nextId(), deviceId);
        } else {
            if (ipv4Dst.prefixLength() == 0) {
                // The entire IPV4_DST field is wildcarded intentionally
                filteredSelector.matchEthType(Ethernet.TYPE_IPV4);
            } else {
                filteredSelector.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(ipv4Dst);
            }
            forTableId = UNICAST_ROUTING_TABLE;
            log.debug("processing IPv4 unicast specific forwarding objective {} -> next:{}" + " in dev:{}", fwd.id(), fwd.nextId(), deviceId);
        }
    } else if (ethType.ethType().toShort() == Ethernet.TYPE_IPV6) {
        IpPrefix ipv6Dst = ((IPCriterion) selector.getCriterion(Criterion.Type.IPV6_DST)).ip();
        if (ipv6Dst.isMulticast()) {
            if (ipv6Dst.prefixLength() != IpAddress.INET6_BIT_LENGTH) {
                log.debug("Multicast specific IPv6 forwarding objective can only be /128");
                fail(fwd, ObjectiveError.BADPARAMS);
                return ImmutableSet.of();
            }
            VlanId assignedVlan = readVlanFromSelector(fwd.meta());
            if (assignedVlan == null) {
                log.debug("VLAN ID required by multicast specific fwd obj is missing. Abort.");
                fail(fwd, ObjectiveError.BADPARAMS);
                return ImmutableSet.of();
            }
            filteredSelector.matchVlanId(assignedVlan);
            filteredSelector.matchEthType(Ethernet.TYPE_IPV6).matchIPv6Dst(ipv6Dst);
            forTableId = MULTICAST_ROUTING_TABLE;
            log.debug("processing IPv6 multicast specific forwarding objective {} -> next:{}" + " in dev:{}", fwd.id(), fwd.nextId(), deviceId);
        } else {
            if (buildIpv6Selector(filteredSelector, fwd) < 0) {
                return Collections.emptyList();
            }
            forTableId = UNICAST_ROUTING_TABLE;
        }
    } else {
        filteredSelector.matchEthType(Ethernet.MPLS_UNICAST).matchMplsLabel(((MplsCriterion) selector.getCriterion(Criterion.Type.MPLS_LABEL)).label());
        MplsBosCriterion bos = (MplsBosCriterion) selector.getCriterion(Criterion.Type.MPLS_BOS);
        if (bos != null) {
            filteredSelector.matchMplsBos(bos.mplsBos());
        }
        forTableId = MPLS_TABLE_1;
        log.debug("processing MPLS specific forwarding objective {} -> next:{}" + " in dev {}", fwd.id(), fwd.nextId(), deviceId);
    }
    TrafficTreatment.Builder tb = DefaultTrafficTreatment.builder();
    if (fwd.treatment() != null) {
        for (Instruction i : fwd.treatment().allInstructions()) {
            if (i instanceof L3ModificationInstruction) {
                L3ModificationInstruction l3instr = (L3ModificationInstruction) i;
                if (l3instr.subtype().equals(L3ModificationInstruction.L3SubType.TTL_IN) || l3instr.subtype().equals(L3ModificationInstruction.L3SubType.TTL_OUT)) {
                    continue;
                }
            }
            /*
                 * NOTE: OF-DPA does not support immediate instruction in
                 * L3 unicast and MPLS table.
                 */
            tb.deferred().add(i);
        }
    }
    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();
            }
            tb.deferred().group(group.id());
        }
    }
    tb.transition(ACL_TABLE);
    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 (defaultRule) {
        flowRuleCollection.add(defaultRoute(fwd, complementarySelector, forTableId, tb));
        log.debug("Default rule 0.0.0.0/0 is being installed two rules");
    }
    return flowRuleCollection;
}
Also used : NextGroup(org.onosproject.net.behaviour.NextGroup) NextGroup(org.onosproject.net.behaviour.NextGroup) Group(org.onosproject.net.group.Group) L3ModificationInstruction(org.onosproject.net.flow.instructions.L3ModificationInstruction) IPCriterion(org.onosproject.net.flow.criteria.IPCriterion) EthTypeCriterion(org.onosproject.net.flow.criteria.EthTypeCriterion) ArrayList(java.util.ArrayList) DefaultTrafficTreatment(org.onosproject.net.flow.DefaultTrafficTreatment) TrafficTreatment(org.onosproject.net.flow.TrafficTreatment) L2ModificationInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction) OutputInstruction(org.onosproject.net.flow.instructions.Instructions.OutputInstruction) L3ModificationInstruction(org.onosproject.net.flow.instructions.L3ModificationInstruction) Instruction(org.onosproject.net.flow.instructions.Instruction) NoActionInstruction(org.onosproject.net.flow.instructions.Instructions.NoActionInstruction) Deque(java.util.Deque) ConnectPoint(org.onosproject.net.ConnectPoint) IpPrefix(org.onlab.packet.IpPrefix) MplsBosCriterion(org.onosproject.net.flow.criteria.MplsBosCriterion) TrafficSelector(org.onosproject.net.flow.TrafficSelector) DefaultTrafficSelector(org.onosproject.net.flow.DefaultTrafficSelector) MplsCriterion(org.onosproject.net.flow.criteria.MplsCriterion) DefaultFlowRule(org.onosproject.net.flow.DefaultFlowRule) FlowRule(org.onosproject.net.flow.FlowRule) VlanId(org.onlab.packet.VlanId)

Example 4 with L3ModificationInstruction

use of org.onosproject.net.flow.instructions.L3ModificationInstruction 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;
}
Also used : NextGroup(org.onosproject.net.behaviour.NextGroup) NextGroup(org.onosproject.net.behaviour.NextGroup) Group(org.onosproject.net.group.Group) IPCriterion(org.onosproject.net.flow.criteria.IPCriterion) ArrayList(java.util.ArrayList) L2ModificationInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction) L2ModificationInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction) L3ModificationInstruction(org.onosproject.net.flow.instructions.L3ModificationInstruction) Instruction(org.onosproject.net.flow.instructions.Instruction) NoActionInstruction(org.onosproject.net.flow.instructions.Instructions.NoActionInstruction) OutputInstruction(org.onosproject.net.flow.instructions.Instructions.OutputInstruction) ModMplsHeaderInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsHeaderInstruction) ModMplsHeaderInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsHeaderInstruction) IpPrefix(org.onlab.packet.IpPrefix) TrafficSelector(org.onosproject.net.flow.TrafficSelector) DefaultTrafficSelector(org.onosproject.net.flow.DefaultTrafficSelector) MplsCriterion(org.onosproject.net.flow.criteria.MplsCriterion) L3ModificationInstruction(org.onosproject.net.flow.instructions.L3ModificationInstruction) EthTypeCriterion(org.onosproject.net.flow.criteria.EthTypeCriterion) DefaultTrafficTreatment(org.onosproject.net.flow.DefaultTrafficTreatment) TrafficTreatment(org.onosproject.net.flow.TrafficTreatment) ArrayDeque(java.util.ArrayDeque) Deque(java.util.Deque) MplsBosCriterion(org.onosproject.net.flow.criteria.MplsBosCriterion) DefaultFlowRule(org.onosproject.net.flow.DefaultFlowRule) FlowRule(org.onosproject.net.flow.FlowRule) Ofdpa3SetMplsType(org.onosproject.driver.extensions.Ofdpa3SetMplsType)

Example 5 with L3ModificationInstruction

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

the class HPPipelineV1 method checkUnSupportedFeatures.

// Return TRUE if ForwardingObjective fwd includes unsupported features
@Override
protected boolean checkUnSupportedFeatures(TrafficSelector selector, TrafficTreatment treatment) {
    boolean unsupportedFeatures = false;
    for (Criterion criterion : selector.criteria()) {
        if (this.unsupportedCriteria.contains(criterion.type())) {
            log.warn("HP V1 Driver - unsupported criteria {}", criterion.type());
            unsupportedFeatures = true;
        }
    }
    for (Instruction instruction : treatment.allInstructions()) {
        if (this.unsupportedInstructions.contains(instruction.type())) {
            log.warn("HP V1 Driver - unsupported instruction {}", instruction.type());
            unsupportedFeatures = true;
        }
        if (instruction.type() == Instruction.Type.L2MODIFICATION) {
            if (this.unsupportedL2mod.contains(((L2ModificationInstruction) instruction).subtype())) {
                log.warn("HP V1 Driver - unsupported L2MODIFICATION instruction {}", ((L2ModificationInstruction) instruction).subtype());
                unsupportedFeatures = true;
            }
        }
        if (instruction.type() == Instruction.Type.L3MODIFICATION) {
            if (this.unsupportedL3mod.contains(((L3ModificationInstruction) instruction).subtype())) {
                log.warn("HP V1 Driver - unsupported L3MODIFICATION instruction {}", ((L3ModificationInstruction) instruction).subtype());
                unsupportedFeatures = true;
            }
        }
    }
    return unsupportedFeatures;
}
Also used : EthTypeCriterion(org.onosproject.net.flow.criteria.EthTypeCriterion) PortCriterion(org.onosproject.net.flow.criteria.PortCriterion) EthCriterion(org.onosproject.net.flow.criteria.EthCriterion) VlanIdCriterion(org.onosproject.net.flow.criteria.VlanIdCriterion) IPCriterion(org.onosproject.net.flow.criteria.IPCriterion) Criterion(org.onosproject.net.flow.criteria.Criterion) L3ModificationInstruction(org.onosproject.net.flow.instructions.L3ModificationInstruction) Instruction(org.onosproject.net.flow.instructions.Instruction) L2ModificationInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction)

Aggregations

L3ModificationInstruction (org.onosproject.net.flow.instructions.L3ModificationInstruction)15 Instruction (org.onosproject.net.flow.instructions.Instruction)11 L2ModificationInstruction (org.onosproject.net.flow.instructions.L2ModificationInstruction)11 IPCriterion (org.onosproject.net.flow.criteria.IPCriterion)9 EthTypeCriterion (org.onosproject.net.flow.criteria.EthTypeCriterion)8 Criterion (org.onosproject.net.flow.criteria.Criterion)7 EthCriterion (org.onosproject.net.flow.criteria.EthCriterion)7 VlanIdCriterion (org.onosproject.net.flow.criteria.VlanIdCriterion)7 PortCriterion (org.onosproject.net.flow.criteria.PortCriterion)6 Ip4Address (org.onlab.packet.Ip4Address)3 DefaultFlowRule (org.onosproject.net.flow.DefaultFlowRule)3 DefaultTrafficSelector (org.onosproject.net.flow.DefaultTrafficSelector)3 DefaultTrafficTreatment (org.onosproject.net.flow.DefaultTrafficTreatment)3 FlowRule (org.onosproject.net.flow.FlowRule)3 TrafficSelector (org.onosproject.net.flow.TrafficSelector)3 TrafficTreatment (org.onosproject.net.flow.TrafficTreatment)3 MplsCriterion (org.onosproject.net.flow.criteria.MplsCriterion)3 L4ModificationInstruction (org.onosproject.net.flow.instructions.L4ModificationInstruction)3 Group (org.onosproject.net.group.Group)3 ArrayDeque (java.util.ArrayDeque)2