blob: c1e2f4da325e1ee9cb7f427ce97e42cd7c8afb6f [file] [log] [blame]
Carmelo Casconeb5324e72018-11-25 02:26:32 -08001/*
2 * Copyright 2018-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.onosproject.pipelines.fabric.pipeliner;
18
19import org.onosproject.net.DeviceId;
20import org.onosproject.net.flow.DefaultFlowRule;
21import org.onosproject.net.flow.DefaultTrafficTreatment;
22import org.onosproject.net.flow.FlowRule;
23import org.onosproject.net.flow.TrafficSelector;
24import org.onosproject.net.flow.TrafficTreatment;
25import org.onosproject.net.flow.instructions.Instruction;
26import org.onosproject.net.flowobjective.Objective;
27import org.onosproject.net.flowobjective.ObjectiveError;
28import org.onosproject.net.pi.model.PiPipelineInterpreter;
29import org.onosproject.net.pi.model.PiTableId;
30import org.onosproject.net.pi.runtime.PiAction;
31import org.onosproject.pipelines.fabric.FabricCapabilities;
32import org.onosproject.pipelines.fabric.FabricInterpreter;
33import org.slf4j.Logger;
34
35import static com.google.common.base.Preconditions.checkNotNull;
36import static java.lang.String.format;
37import static org.slf4j.LoggerFactory.getLogger;
38
39/**
40 * Abstract implementation of a pipeliner logic for the fabric pipeconf.
41 */
42abstract class AbstractObjectiveTranslator<T extends Objective> {
43
44 protected final Logger log = getLogger(this.getClass());
45
46 protected final FabricCapabilities capabilities;
47 protected final DeviceId deviceId;
48
49 private final PiPipelineInterpreter interpreter = new FabricInterpreter();
50
51 AbstractObjectiveTranslator(DeviceId deviceId, FabricCapabilities capabilities) {
52 this.deviceId = checkNotNull(deviceId);
53 this.capabilities = checkNotNull(capabilities);
54 }
55
56 public ObjectiveTranslation translate(T obj) {
57 try {
58 return doTranslate(obj);
59 } catch (FabricPipelinerException e) {
60 log.warn("Cannot translate {}: {} [{}]",
61 obj.getClass().getSimpleName(), e.getMessage(), obj);
62 return ObjectiveTranslation.ofError(e.objectiveError());
63 }
64 }
65
66 public abstract ObjectiveTranslation doTranslate(T obj)
67 throws FabricPipelinerException;
68
69 public FlowRule flowRule(T obj, PiTableId tableId, TrafficSelector selector,
70 TrafficTreatment treatment)
71 throws FabricPipelinerException {
72 return DefaultFlowRule.builder()
73 .withSelector(selector)
74 .withTreatment(mapTreatmentToPiIfNeeded(treatment, tableId))
75 .forTable(tableId)
76 .makePermanent()
77 .withPriority(obj.priority())
78 .forDevice(deviceId)
79 .fromApp(obj.appId())
80 .build();
81 }
82
83 TrafficTreatment mapTreatmentToPiIfNeeded(TrafficTreatment treatment, PiTableId tableId)
84 throws FabricPipelinerException {
85 if (isTreatmentPi(treatment)) {
86 return treatment;
87 }
88 final PiAction piAction;
89 try {
90 piAction = interpreter.mapTreatment(treatment, tableId);
91 } catch (PiPipelineInterpreter.PiInterpreterException ex) {
92 throw new FabricPipelinerException(
93 format("Unable to map treatment for table '%s': %s",
94 tableId, ex.getMessage()),
95 ObjectiveError.UNSUPPORTED);
96 }
97 return DefaultTrafficTreatment.builder()
98 .piTableAction(piAction)
99 .build();
100 }
101
102 private boolean isTreatmentPi(TrafficTreatment treatment) {
103 return treatment.allInstructions().size() == 1
104 && treatment.allInstructions().get(0).type() == Instruction.Type.PROTOCOL_INDEPENDENT;
105 }
106}