blob: bd4969020b926de396cb6421016cab2e16469b2d [file] [log] [blame]
HelloONOSaf3b4282017-06-27 16:27:31 +09001/*
2 * Copyright 2017-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 */
16package org.onosproject.driver.pipeline;
17
18import static org.slf4j.LoggerFactory.getLogger;
19
20import java.util.List;
21import java.util.Optional;
22
23
24import com.google.common.collect.ImmutableList;
25import org.onlab.osgi.ServiceDirectory;
26import org.onosproject.net.DeviceId;
27import org.onosproject.net.Device;
28import org.onosproject.net.behaviour.NextGroup;
29import org.onosproject.net.behaviour.Pipeliner;
30import org.onosproject.net.behaviour.PipelinerContext;
31import org.onosproject.net.device.DeviceService;
32import org.onosproject.net.flow.DefaultFlowRule;
33import org.onosproject.net.flow.FlowRule;
34import org.onosproject.net.flow.FlowRuleOperations;
35import org.onosproject.net.flow.FlowRuleOperationsContext;
36import org.onosproject.net.flow.FlowRuleService;
37import org.onosproject.net.flow.DefaultTrafficTreatment;
38import org.onosproject.net.flow.TrafficTreatment;
39import org.onosproject.net.flowobjective.DefaultForwardingObjective;
40import org.onosproject.net.flowobjective.FilteringObjective;
41import org.onosproject.net.flowobjective.ForwardingObjective;
42import org.onosproject.net.flowobjective.NextObjective;
43import org.onosproject.net.flowobjective.Objective;
44import org.onosproject.net.flowobjective.ObjectiveError;
45import org.slf4j.Logger;
46
47
48/**
49 * Simple single table pipeline abstraction.
50 */
51public class JuniperPipeliner extends DefaultSingleTablePipeline implements Pipeliner {
52
53 private final Logger log = getLogger(getClass());
54
55 //Juniper Switch Default flow table starts from 1
56 private static final int DEFAULT_TABLE = 1;
57
58 private ServiceDirectory serviceDirectory;
59 private DeviceId deviceId;
60 private FlowRuleService flowRuleService;
61
62 protected DeviceService deviceService;
63 @Override
64 public void init(DeviceId deviceId, PipelinerContext context) {
65 this.deviceId = deviceId;
66 this.serviceDirectory = context.directory();
67 this.flowRuleService = serviceDirectory.get(FlowRuleService.class);
68 this.deviceService = serviceDirectory.get(DeviceService.class);
69 }
70
71 @Override
72 public void filter(FilteringObjective filterObjective) {
73 //Do nothing
74 log.info("No action is needed here");
75 }
76
77 @Override
78 public void forward(ForwardingObjective forwardObjective) {
79 FlowRule rule;
80 FlowRuleOperations.Builder flowOpsBuilder = FlowRuleOperations.builder();
81
82 ForwardingObjective newFwd = forwardObjective;
83
84 Device device = deviceService.getDevice(deviceId);
85 if (forwardObjective.treatment() != null && forwardObjective.treatment().clearedDeferred()) {
86 log.warn("Using 'clear actions' instruction which is not supported by {} " + " {} " + "{} Switch ",
87 device.id(), device.manufacturer(), device.hwVersion());
88 newFwd = forwardingObjectiveWithoutCleardDef(forwardObjective).orElse(forwardObjective);
89 }
90
91 rule = processForward(newFwd);
92 switch (forwardObjective.op()) {
93 case ADD:
94 flowOpsBuilder.add(rule);
95 break;
96 case REMOVE:
97 flowOpsBuilder.remove(rule);
98 break;
99 default:
100 fail(forwardObjective, ObjectiveError.UNKNOWN);
101 log.warn("Unknown forwarding type {}", forwardObjective.op());
102 }
103
104 flowRuleService.apply(flowOpsBuilder.build(new FlowRuleOperationsContext() {
105 @Override
106 public void onSuccess(FlowRuleOperations ops) {
107 pass(forwardObjective);
108 }
109
110 @Override
111 public void onError(FlowRuleOperations ops) {
112 fail(forwardObjective, ObjectiveError.FLOWINSTALLATIONFAILED);
113 }
114 }));
115 }
116
117 private Optional<ForwardingObjective> forwardingObjectiveWithoutCleardDef(ForwardingObjective forwardingObjective) {
118
119 TrafficTreatment treatment = trafficTreatmentWithoutCleardDeffered(forwardingObjective.treatment());
120
121 DefaultForwardingObjective.Builder foBuilder = (DefaultForwardingObjective.Builder) forwardingObjective.copy();
122 foBuilder.withTreatment(treatment);
123
124
125 switch (forwardingObjective.op()) {
126 case ADD:
127 return Optional.of(foBuilder.add(forwardingObjective.context().orElse(null)));
128 case REMOVE:
129 return Optional.of(foBuilder.remove(forwardingObjective.context().orElse(null)));
130 default:
131 log.warn("Driver Not support other operations for forwarding objective");
132 return Optional.empty();
133 }
134 }
135
136 private TrafficTreatment trafficTreatmentWithoutCleardDeffered(TrafficTreatment treatment) {
137 return DefaultTrafficTreatment.builder(treatment)
138 .notWipeDeferred()
139 .build();
140 }
141
142 private FlowRule processForward(ForwardingObjective fwd) {
143
144 FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
145 .forDevice(deviceId)
146 .withSelector(fwd.selector())
147 .withTreatment(fwd.treatment())
148 .withPriority(fwd.priority())
149 .fromApp(fwd.appId())
150 .forTable(DEFAULT_TABLE);
151 if (fwd.permanent()) {
152 ruleBuilder.makePermanent();
153 } else {
154 ruleBuilder.makeTemporary(fwd.timeout());
155 }
156
157 return ruleBuilder.build();
158
159 }
160
161 @Override
162 public void next(NextObjective nextObjective) {
163 //Do nothing
164 log.info("no action is needed here");
165 }
166
167 @Override
168 public List<String> getNextMappings(NextGroup nextGroup) {
169
170 return ImmutableList.of();
171 }
172
173 private void pass(Objective obj) {
174 obj.context().ifPresent(context -> context.onSuccess(obj));
175 }
176
177 private void fail(Objective obj, ObjectiveError error) {
178 obj.context().ifPresent(context -> context.onError(obj, error));
179 }
180}