blob: 270e76a20bfe12a47bf10a4107ea48e93f8d73ca [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;
samuel3b2743d2015-07-29 10:44:30 +080029import org.onosproject.net.flow.DefaultFlowRule;
30import org.onosproject.net.flow.DefaultTrafficTreatment;
31import org.onosproject.net.flow.FlowRule;
32import org.onosproject.net.flow.FlowRuleOperations;
33import org.onosproject.net.flow.FlowRuleOperationsContext;
34import org.onosproject.net.flow.FlowRuleService;
35import org.onosproject.net.flow.TrafficSelector;
36import org.onosproject.net.flow.TrafficTreatment;
37import org.onosproject.net.flow.criteria.Criterion.Type;
38import org.onosproject.net.flow.instructions.Instructions;
39import org.onosproject.net.flowobjective.FilteringObjective;
40import org.onosproject.net.flowobjective.FlowObjectiveStore;
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 * Driver for standard OpenVSwitch.
49 */
CNluciusa66c3972015-09-06 20:31:29 +080050public class OpenVSwitchPipeline extends DefaultSingleTablePipeline
samuel3b2743d2015-07-29 10:44:30 +080051 implements Pipeliner {
52
CNluciusa66c3972015-09-06 20:31:29 +080053 private static final String VTN_APP_ID = "org.onosproject.app.vtn";
samuel3b2743d2015-07-29 10:44:30 +080054 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;
samuel3b2743d2015-07-29 10:44:30 +080061 private static final int TIME_OUT = 0;
62 private static final int MAC_TABLE = 40;
63 private static final int PORT_TABLE = 0;
64
65 @Override
66 public void init(DeviceId deviceId, PipelinerContext context) {
CNluciusa66c3972015-09-06 20:31:29 +080067 super.init(deviceId, context);
samuel3b2743d2015-07-29 10:44:30 +080068 this.serviceDirectory = context.directory();
69 this.deviceId = deviceId;
70
71 coreService = serviceDirectory.get(CoreService.class);
72 flowRuleService = serviceDirectory.get(FlowRuleService.class);
73 flowObjectiveStore = context.store();
74 coreService
75 .registerApplication("org.onosproject.driver.OpenVSwitchPipeline");
76
77 }
78
79 @Override
80 public void filter(FilteringObjective filteringObjective) {
CNluciusa66c3972015-09-06 20:31:29 +080081 super.filter(filteringObjective);
samuel3b2743d2015-07-29 10:44:30 +080082 }
83
84 @Override
85 public void forward(ForwardingObjective fwd) {
CNluciusa66c3972015-09-06 20:31:29 +080086 if (!VTN_APP_ID.equals(fwd.appId().name())) {
87 super.forward(fwd);
88 return;
89 }
samuel3b2743d2015-07-29 10:44:30 +080090 Collection<FlowRule> rules;
91 FlowRuleOperations.Builder flowOpsBuilder = FlowRuleOperations
92 .builder();
93
94 rules = processForward(fwd);
95 switch (fwd.op()) {
96 case ADD:
97 rules.stream().filter(rule -> rule != null)
98 .forEach(flowOpsBuilder::add);
99 break;
100 case REMOVE:
101 rules.stream().filter(rule -> rule != null)
102 .forEach(flowOpsBuilder::remove);
103 break;
104 default:
105 fail(fwd, ObjectiveError.UNKNOWN);
106 log.warn("Unknown forwarding type {}", fwd.op());
107 }
108
109 flowRuleService.apply(flowOpsBuilder
110 .build(new FlowRuleOperationsContext() {
111 @Override
112 public void onSuccess(FlowRuleOperations ops) {
113 pass(fwd);
114 }
115
116 @Override
117 public void onError(FlowRuleOperations ops) {
118 fail(fwd, ObjectiveError.FLOWINSTALLATIONFAILED);
119 }
120 }));
121 }
122
123 @Override
124 public void next(NextObjective nextObjective) {
CNluciusa66c3972015-09-06 20:31:29 +0800125 super.next(nextObjective);
samuel3b2743d2015-07-29 10:44:30 +0800126 }
127
128 private Collection<FlowRule> processForward(ForwardingObjective fwd) {
129 switch (fwd.flag()) {
130 case SPECIFIC:
131 return processSpecific(fwd);
132 case VERSATILE:
133 return processVersatile(fwd);
134 default:
135 fail(fwd, ObjectiveError.UNKNOWN);
136 log.warn("Unknown forwarding flag {}", fwd.flag());
137 }
138 return Collections.emptySet();
139 }
140
141 private Collection<FlowRule> processVersatile(ForwardingObjective fwd) {
142 log.debug("Processing versatile forwarding objective");
143 return Collections.emptyList();
144 }
145
146 private Collection<FlowRule> processSpecific(ForwardingObjective fwd) {
147 log.debug("Processing specific forwarding objective");
148 TrafficSelector selector = fwd.selector();
149 TrafficTreatment tb = fwd.treatment();
150 FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
151 .fromApp(fwd.appId()).withPriority(fwd.priority())
152 .forDevice(deviceId).withSelector(selector)
CNluciusa66c3972015-09-06 20:31:29 +0800153 .withTreatment(tb).makeTemporary(TIME_OUT);
154 ruleBuilder.withPriority(fwd.priority());
samuel3b2743d2015-07-29 10:44:30 +0800155 if (fwd.permanent()) {
156 ruleBuilder.makePermanent();
157 }
158 if (selector.getCriterion(Type.ETH_DST) != null
159 || tb.allInstructions().contains(Instructions.createDrop())) {
samuel3b2743d2015-07-29 10:44:30 +0800160 ruleBuilder.withTreatment(tb);
161 ruleBuilder.forTable(MAC_TABLE);
162 } else {
samuel3b2743d2015-07-29 10:44:30 +0800163 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}