blob: c630131919141b25d19bed6a3c5b107b0bbb6ed4 [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 {
Daniele Moro693d76f2019-09-24 14:34:07 -070073 return flowRule(obj, tableId, selector, treatment, obj.priority());
74 }
75
76 public FlowRule flowRule(T obj, PiTableId tableId, TrafficSelector selector,
77 TrafficTreatment treatment, Integer priority)
78 throws FabricPipelinerException {
Carmelo Casconeb5324e72018-11-25 02:26:32 -080079 return DefaultFlowRule.builder()
80 .withSelector(selector)
81 .withTreatment(mapTreatmentToPiIfNeeded(treatment, tableId))
82 .forTable(tableId)
83 .makePermanent()
Daniele Moro693d76f2019-09-24 14:34:07 -070084 .withPriority(priority)
Carmelo Casconeb5324e72018-11-25 02:26:32 -080085 .forDevice(deviceId)
86 .fromApp(obj.appId())
87 .build();
88 }
89
90 TrafficTreatment mapTreatmentToPiIfNeeded(TrafficTreatment treatment, PiTableId tableId)
91 throws FabricPipelinerException {
92 if (isTreatmentPi(treatment)) {
93 return treatment;
94 }
95 final PiAction piAction;
96 try {
97 piAction = interpreter.mapTreatment(treatment, tableId);
98 } catch (PiPipelineInterpreter.PiInterpreterException ex) {
99 throw new FabricPipelinerException(
100 format("Unable to map treatment for table '%s': %s",
101 tableId, ex.getMessage()),
102 ObjectiveError.UNSUPPORTED);
103 }
104 return DefaultTrafficTreatment.builder()
105 .piTableAction(piAction)
106 .build();
107 }
108
109 private boolean isTreatmentPi(TrafficTreatment treatment) {
110 return treatment.allInstructions().size() == 1
111 && treatment.allInstructions().get(0).type() == Instruction.Type.PROTOCOL_INDEPENDENT;
112 }
113}