blob: fd728e9db084362dc48ab3576db3e73173944c45 [file] [log] [blame]
samuel3b2743d2015-07-29 10:44:30 +08001/*
2 * Copyright 2015 Open Networking Laboratory
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.Collection;
21import java.util.Collections;
22
23import org.onlab.osgi.ServiceDirectory;
24import org.onosproject.core.CoreService;
25import org.onosproject.net.DeviceId;
26import org.onosproject.net.behaviour.Pipeliner;
27import org.onosproject.net.behaviour.PipelinerContext;
28import org.onosproject.net.device.DeviceService;
29import org.onosproject.net.driver.AbstractHandlerBehaviour;
30import org.onosproject.net.flow.DefaultFlowRule;
31import org.onosproject.net.flow.DefaultTrafficTreatment;
32import org.onosproject.net.flow.FlowRule;
33import org.onosproject.net.flow.FlowRuleOperations;
34import org.onosproject.net.flow.FlowRuleOperationsContext;
35import org.onosproject.net.flow.FlowRuleService;
36import org.onosproject.net.flow.TrafficSelector;
37import org.onosproject.net.flow.TrafficTreatment;
38import org.onosproject.net.flow.criteria.Criterion.Type;
39import org.onosproject.net.flow.instructions.Instructions;
40import org.onosproject.net.flowobjective.FilteringObjective;
41import org.onosproject.net.flowobjective.FlowObjectiveStore;
42import org.onosproject.net.flowobjective.ForwardingObjective;
43import org.onosproject.net.flowobjective.NextObjective;
44import org.onosproject.net.flowobjective.Objective;
45import org.onosproject.net.flowobjective.ObjectiveError;
46import org.slf4j.Logger;
47
48/**
49 * Driver for standard OpenVSwitch.
50 */
51public class OpenVSwitchPipeline extends AbstractHandlerBehaviour
52 implements Pipeliner {
53
54 private final Logger log = getLogger(getClass());
55 private CoreService coreService;
56 private ServiceDirectory serviceDirectory;
57 protected FlowObjectiveStore flowObjectiveStore;
58 protected DeviceId deviceId;
59 protected FlowRuleService flowRuleService;
60 protected DeviceService deviceService;
61 private static final int MAC_TABLE_PRIORITY = 0xffff;
62 private static final int PORT_TABLE_PRIORITY = 0xffff;
63 private static final int TIME_OUT = 0;
64 private static final int MAC_TABLE = 40;
65 private static final int PORT_TABLE = 0;
66
67 @Override
68 public void init(DeviceId deviceId, PipelinerContext context) {
69 this.serviceDirectory = context.directory();
70 this.deviceId = deviceId;
71
72 coreService = serviceDirectory.get(CoreService.class);
73 flowRuleService = serviceDirectory.get(FlowRuleService.class);
74 flowObjectiveStore = context.store();
75 coreService
76 .registerApplication("org.onosproject.driver.OpenVSwitchPipeline");
77
78 }
79
80 @Override
81 public void filter(FilteringObjective filteringObjective) {
82 // TODO Auto-generated method stub
83 }
84
85 @Override
86 public void forward(ForwardingObjective fwd) {
87 Collection<FlowRule> rules;
88 FlowRuleOperations.Builder flowOpsBuilder = FlowRuleOperations
89 .builder();
90
91 rules = processForward(fwd);
92 switch (fwd.op()) {
93 case ADD:
94 rules.stream().filter(rule -> rule != null)
95 .forEach(flowOpsBuilder::add);
96 break;
97 case REMOVE:
98 rules.stream().filter(rule -> rule != null)
99 .forEach(flowOpsBuilder::remove);
100 break;
101 default:
102 fail(fwd, ObjectiveError.UNKNOWN);
103 log.warn("Unknown forwarding type {}", fwd.op());
104 }
105
106 flowRuleService.apply(flowOpsBuilder
107 .build(new FlowRuleOperationsContext() {
108 @Override
109 public void onSuccess(FlowRuleOperations ops) {
110 pass(fwd);
111 }
112
113 @Override
114 public void onError(FlowRuleOperations ops) {
115 fail(fwd, ObjectiveError.FLOWINSTALLATIONFAILED);
116 }
117 }));
118 }
119
120 @Override
121 public void next(NextObjective nextObjective) {
122 // TODO Auto-generated method stub
123
124 }
125
126 private Collection<FlowRule> processForward(ForwardingObjective fwd) {
127 switch (fwd.flag()) {
128 case SPECIFIC:
129 return processSpecific(fwd);
130 case VERSATILE:
131 return processVersatile(fwd);
132 default:
133 fail(fwd, ObjectiveError.UNKNOWN);
134 log.warn("Unknown forwarding flag {}", fwd.flag());
135 }
136 return Collections.emptySet();
137 }
138
139 private Collection<FlowRule> processVersatile(ForwardingObjective fwd) {
140 log.debug("Processing versatile forwarding objective");
141 return Collections.emptyList();
142 }
143
144 private Collection<FlowRule> processSpecific(ForwardingObjective fwd) {
145 log.debug("Processing specific forwarding objective");
146 TrafficSelector selector = fwd.selector();
147 TrafficTreatment tb = fwd.treatment();
148 FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
149 .fromApp(fwd.appId()).withPriority(fwd.priority())
150 .forDevice(deviceId).withSelector(selector)
151 .makeTemporary(TIME_OUT);
152
153 if (fwd.permanent()) {
154 ruleBuilder.makePermanent();
155 }
156 if (selector.getCriterion(Type.ETH_DST) != null
157 || tb.allInstructions().contains(Instructions.createDrop())) {
158 ruleBuilder.withPriority(MAC_TABLE_PRIORITY);
159 ruleBuilder.withTreatment(tb);
160 ruleBuilder.forTable(MAC_TABLE);
161 } else {
162 ruleBuilder.withPriority(PORT_TABLE_PRIORITY);
163 TrafficTreatment.Builder newTraffic = DefaultTrafficTreatment.builder();
164 tb.allInstructions().forEach(t -> newTraffic.add(t));
165 newTraffic.transition(MAC_TABLE);
166 ruleBuilder.withTreatment(newTraffic.build());
167 ruleBuilder.forTable(PORT_TABLE);
168 }
169 return Collections.singletonList(ruleBuilder.build());
170 }
171
172 private void fail(Objective obj, ObjectiveError error) {
173 if (obj.context().isPresent()) {
174 obj.context().get().onError(obj, error);
175 }
176 }
177
178 private void pass(Objective obj) {
179 if (obj.context().isPresent()) {
180 obj.context().get().onSuccess(obj);
181 }
182 }
183}