summaryrefslogtreecommitdiffstats
path: root/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/MplsPathIntentCompiler.java
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/MplsPathIntentCompiler.java')
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/MplsPathIntentCompiler.java320
1 files changed, 0 insertions, 320 deletions
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/MplsPathIntentCompiler.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/MplsPathIntentCompiler.java
deleted file mode 100644
index 5549918c..00000000
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/MplsPathIntentCompiler.java
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.net.intent.impl.compiler;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Sets;
-
-import org.apache.felix.scr.annotations.Activate;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Deactivate;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.ReferenceCardinality;
-import org.onlab.packet.EthType;
-import org.onlab.packet.Ethernet;
-import org.onlab.packet.MplsLabel;
-import org.onlab.packet.VlanId;
-import org.onosproject.core.ApplicationId;
-import org.onosproject.core.CoreService;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.Link;
-import org.onosproject.net.LinkKey;
-import org.onosproject.net.PortNumber;
-import org.onosproject.net.flow.DefaultFlowRule;
-import org.onosproject.net.flow.DefaultTrafficSelector;
-import org.onosproject.net.flow.DefaultTrafficTreatment;
-import org.onosproject.net.flow.FlowRule;
-import org.onosproject.net.flow.TrafficSelector;
-import org.onosproject.net.flow.TrafficTreatment;
-import org.onosproject.net.flow.criteria.Criterion;
-import org.onosproject.net.flow.criteria.EthTypeCriterion;
-import org.onosproject.net.flow.instructions.Instruction;
-import org.onosproject.net.flow.instructions.L2ModificationInstruction;
-import org.onosproject.net.intent.FlowRuleIntent;
-import org.onosproject.net.intent.Intent;
-import org.onosproject.net.intent.IntentCompiler;
-import org.onosproject.net.intent.IntentExtensionService;
-import org.onosproject.net.intent.MplsPathIntent;
-import org.onosproject.net.newresource.ResourcePath;
-import org.onosproject.net.newresource.ResourceService;
-import org.onosproject.net.resource.link.LinkResourceAllocations;
-import org.slf4j.Logger;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.onosproject.net.LinkKey.linkKey;
-import static org.slf4j.LoggerFactory.getLogger;
-
-@Component(immediate = true)
-public class MplsPathIntentCompiler implements IntentCompiler<MplsPathIntent> {
-
- private final Logger log = getLogger(getClass());
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected IntentExtensionService intentExtensionService;
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected CoreService coreService;
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected ResourceService resourceService;
-
- protected ApplicationId appId;
-
- @Override
- public List<Intent> compile(MplsPathIntent intent, List<Intent> installable,
- Set<LinkResourceAllocations> resources) {
- Map<LinkKey, MplsLabel> labels = assignMplsLabel(intent);
- List<FlowRule> rules = generateRules(intent, labels);
-
- return Collections.singletonList(new FlowRuleIntent(appId, rules, intent.resources()));
- }
-
- @Activate
- public void activate() {
- appId = coreService.registerApplication("org.onosproject.net.intent");
- intentExtensionService.registerCompiler(MplsPathIntent.class, this);
- }
-
- @Deactivate
- public void deactivate() {
- intentExtensionService.unregisterCompiler(MplsPathIntent.class);
- }
-
- private Map<LinkKey, MplsLabel> assignMplsLabel(MplsPathIntent intent) {
- // TODO: do it better... Suggestions?
- Set<LinkKey> linkRequest = Sets.newHashSetWithExpectedSize(intent.path()
- .links().size() - 2);
- for (int i = 1; i <= intent.path().links().size() - 2; i++) {
- LinkKey link = linkKey(intent.path().links().get(i));
- linkRequest.add(link);
- // add the inverse link. I want that the label is reserved both for
- // the direct and inverse link
- linkRequest.add(linkKey(link.dst(), link.src()));
- }
-
- Map<LinkKey, MplsLabel> labels = findMplsLabels(linkRequest);
- if (labels.isEmpty()) {
- return Collections.emptyMap();
- }
-
- // for short term solution: same label is used for both directions
- // TODO: introduce the concept of Tx and Rx resources of a port
- Set<ResourcePath> resources = labels.entrySet().stream()
- .flatMap(x -> Stream.of(
- ResourcePath.discrete(x.getKey().src().deviceId(), x.getKey().src().port(), x.getValue()),
- ResourcePath.discrete(x.getKey().dst().deviceId(), x.getKey().dst().port(), x.getValue())
- ))
- .collect(Collectors.toSet());
- List<org.onosproject.net.newresource.ResourceAllocation> allocations =
- resourceService.allocate(intent.id(), ImmutableList.copyOf(resources));
- if (allocations.isEmpty()) {
- Collections.emptyMap();
- }
-
- return labels;
- }
-
- private Map<LinkKey, MplsLabel> findMplsLabels(Set<LinkKey> links) {
- Map<LinkKey, MplsLabel> labels = new HashMap<>();
- for (LinkKey link : links) {
- Set<MplsLabel> forward = findMplsLabel(link.src());
- Set<MplsLabel> backward = findMplsLabel(link.dst());
- Set<MplsLabel> common = Sets.intersection(forward, backward);
- if (common.isEmpty()) {
- continue;
- }
- labels.put(link, common.iterator().next());
- }
-
- return labels;
- }
-
- private Set<MplsLabel> findMplsLabel(ConnectPoint cp) {
- return resourceService.getAvailableResources(ResourcePath.discrete(cp.deviceId(), cp.port())).stream()
- .filter(x -> x.last() instanceof MplsLabel)
- .map(x -> (MplsLabel) x.last())
- .collect(Collectors.toSet());
- }
-
- private MplsLabel getMplsLabel(Map<LinkKey, MplsLabel> labels, LinkKey link) {
- return labels.get(link);
- }
-
- private List<FlowRule> generateRules(MplsPathIntent intent,
- Map<LinkKey, MplsLabel> labels) {
-
- Iterator<Link> links = intent.path().links().iterator();
- Link srcLink = links.next();
- ConnectPoint prev = srcLink.dst();
-
- Link link = links.next();
- // List of flow rules to be installed
- List<FlowRule> rules = new LinkedList<>();
-
- // Ingress traffic
- // Get the new MPLS label
- MplsLabel mpls = getMplsLabel(labels, linkKey(link));
- checkNotNull(mpls);
- MplsLabel prevLabel = mpls;
- rules.add(ingressFlow(prev.port(), link, intent, mpls));
-
- prev = link.dst();
-
- while (links.hasNext()) {
-
- link = links.next();
-
- if (links.hasNext()) {
- // Transit traffic
- // Get the new MPLS label
- mpls = getMplsLabel(labels, linkKey(link));
- checkNotNull(mpls);
- rules.add(transitFlow(prev.port(), link, intent,
- prevLabel, mpls));
- prevLabel = mpls;
-
- } else {
- // Egress traffic
- rules.add(egressFlow(prev.port(), link, intent,
- prevLabel));
- }
-
- prev = link.dst();
- }
- return rules;
- }
-
- private FlowRule ingressFlow(PortNumber inPort, Link link,
- MplsPathIntent intent,
- MplsLabel label) {
-
- TrafficSelector.Builder ingressSelector = DefaultTrafficSelector
- .builder(intent.selector());
- TrafficTreatment.Builder treat = DefaultTrafficTreatment.builder();
- ingressSelector.matchInPort(inPort);
-
- if (intent.ingressLabel().isPresent()) {
- ingressSelector.matchEthType(Ethernet.MPLS_UNICAST)
- .matchMplsLabel(intent.ingressLabel().get());
-
- // Swap the MPLS label
- treat.setMpls(label);
- } else {
- // Push and set the MPLS label
- treat.pushMpls().setMpls(label);
- }
- // Add the output action
- treat.setOutput(link.src().port());
-
- return createFlowRule(intent, link.src().deviceId(), ingressSelector.build(), treat.build());
- }
-
- private FlowRule transitFlow(PortNumber inPort, Link link,
- MplsPathIntent intent,
- MplsLabel prevLabel,
- MplsLabel outLabel) {
-
- // Ignore the ingress Traffic Selector and use only the MPLS label
- // assigned in the previous link
- TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
- selector.matchInPort(inPort).matchEthType(Ethernet.MPLS_UNICAST)
- .matchMplsLabel(prevLabel);
- TrafficTreatment.Builder treat = DefaultTrafficTreatment.builder();
-
- // Set the new label only if the label on the packet is
- // different
- if (!prevLabel.equals(outLabel)) {
- treat.setMpls(outLabel);
- }
-
- treat.setOutput(link.src().port());
- return createFlowRule(intent, link.src().deviceId(), selector.build(), treat.build());
- }
-
- private FlowRule egressFlow(PortNumber inPort, Link link,
- MplsPathIntent intent,
- MplsLabel prevLabel) {
- // egress point: either set the egress MPLS label or pop the
- // MPLS label based on the intent annotations
-
- TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
- selector.matchInPort(inPort).matchEthType(Ethernet.MPLS_UNICAST)
- .matchMplsLabel(prevLabel);
-
- // apply the intent's treatments
- TrafficTreatment.Builder treat = DefaultTrafficTreatment.builder(intent
- .treatment());
-
- // check if the treatement is popVlan or setVlan (rewrite),
- // than selector needs to match any VlanId
- for (Instruction instruct : intent.treatment().allInstructions()) {
- if (instruct instanceof L2ModificationInstruction) {
- L2ModificationInstruction l2Mod = (L2ModificationInstruction) instruct;
- if (l2Mod.subtype() == L2ModificationInstruction.L2SubType.VLAN_PUSH) {
- break;
- }
- if (l2Mod.subtype() == L2ModificationInstruction.L2SubType.VLAN_POP ||
- l2Mod.subtype() == L2ModificationInstruction.L2SubType.VLAN_ID) {
- selector.matchVlanId(VlanId.ANY);
- }
- }
- }
-
- if (intent.egressLabel().isPresent()) {
- treat.setMpls(intent.egressLabel().get());
- } else {
- treat.popMpls(outputEthType(intent.selector()));
- }
- treat.setOutput(link.src().port());
- return createFlowRule(intent, link.src().deviceId(),
- selector.build(), treat.build());
- }
-
- protected FlowRule createFlowRule(MplsPathIntent intent, DeviceId deviceId,
- TrafficSelector selector, TrafficTreatment treat) {
- return DefaultFlowRule.builder()
- .forDevice(deviceId)
- .withSelector(selector)
- .withTreatment(treat)
- .withPriority(intent.priority())
- .fromApp(appId)
- .makePermanent()
- .build();
- }
-
- // if the ingress ethertype is defined, the egress traffic
- // will be use that value, otherwise the IPv4 ethertype is used.
- private EthType outputEthType(TrafficSelector selector) {
- Criterion c = selector.getCriterion(Criterion.Type.ETH_TYPE);
- if (c != null && c instanceof EthTypeCriterion) {
- EthTypeCriterion ethertype = (EthTypeCriterion) c;
- return ethertype.ethType();
- } else {
- return EthType.EtherType.IPV4.ethType();
- }
- }
-}