blob: 5b9671f0ad8110a5ce51a8acd123af9f2dd89a24 [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
Carmelo Cascone36d5e7a2019-09-25 01:02:53 -070017package org.onosproject.pipelines.fabric.impl.behaviour.pipeliner;
Carmelo Casconeb5324e72018-11-25 02:26:32 -080018
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;
Carmelo Cascone36d5e7a2019-09-25 01:02:53 -070031import org.onosproject.pipelines.fabric.impl.behaviour.FabricCapabilities;
32import org.onosproject.pipelines.fabric.impl.behaviour.FabricInterpreter;
Carmelo Casconeb5324e72018-11-25 02:26:32 -080033import 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
Daniele Moro77ef35c2019-07-30 10:43:10 -070049 private final PiPipelineInterpreter interpreter;
Carmelo Casconeb5324e72018-11-25 02:26:32 -080050
51 AbstractObjectiveTranslator(DeviceId deviceId, FabricCapabilities capabilities) {
52 this.deviceId = checkNotNull(deviceId);
53 this.capabilities = checkNotNull(capabilities);
Daniele Moro77ef35c2019-07-30 10:43:10 -070054 this.interpreter = new FabricInterpreter(capabilities);
Carmelo Casconeb5324e72018-11-25 02:26:32 -080055 }
56
57 public ObjectiveTranslation translate(T obj) {
58 try {
59 return doTranslate(obj);
60 } catch (FabricPipelinerException e) {
61 log.warn("Cannot translate {}: {} [{}]",
62 obj.getClass().getSimpleName(), e.getMessage(), obj);
63 return ObjectiveTranslation.ofError(e.objectiveError());
64 }
65 }
66
67 public abstract ObjectiveTranslation doTranslate(T obj)
68 throws FabricPipelinerException;
69
70 public FlowRule flowRule(T obj, PiTableId tableId, TrafficSelector selector,
71 TrafficTreatment treatment)
72 throws FabricPipelinerException {
73 return DefaultFlowRule.builder()
74 .withSelector(selector)
75 .withTreatment(mapTreatmentToPiIfNeeded(treatment, tableId))
76 .forTable(tableId)
77 .makePermanent()
78 .withPriority(obj.priority())
79 .forDevice(deviceId)
80 .fromApp(obj.appId())
81 .build();
82 }
83
84 TrafficTreatment mapTreatmentToPiIfNeeded(TrafficTreatment treatment, PiTableId tableId)
85 throws FabricPipelinerException {
86 if (isTreatmentPi(treatment)) {
87 return treatment;
88 }
89 final PiAction piAction;
90 try {
91 piAction = interpreter.mapTreatment(treatment, tableId);
92 } catch (PiPipelineInterpreter.PiInterpreterException ex) {
93 throw new FabricPipelinerException(
94 format("Unable to map treatment for table '%s': %s",
95 tableId, ex.getMessage()),
96 ObjectiveError.UNSUPPORTED);
97 }
98 return DefaultTrafficTreatment.builder()
99 .piTableAction(piAction)
100 .build();
101 }
102
103 private boolean isTreatmentPi(TrafficTreatment treatment) {
104 return treatment.allInstructions().size() == 1
105 && treatment.allInstructions().get(0).type() == Instruction.Type.PROTOCOL_INDEPENDENT;
106 }
107}