blob: 79d2b0a82fa98fdd96219c8c8bc4164e5ccde8de [file] [log] [blame]
alshabib0ccde6d2015-05-30 18:22:36 -07001/*
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 org.onlab.osgi.ServiceDirectory;
alshabibb32cefe2015-06-08 18:15:05 -070019import org.onlab.packet.Ethernet;
20import org.onosproject.core.ApplicationId;
alshabib0ccde6d2015-05-30 18:22:36 -070021import org.onosproject.net.DeviceId;
22import org.onosproject.net.PortNumber;
23import org.onosproject.net.behaviour.Pipeliner;
24import org.onosproject.net.behaviour.PipelinerContext;
25import org.onosproject.net.driver.AbstractHandlerBehaviour;
26import org.onosproject.net.flow.DefaultFlowRule;
alshabibb32cefe2015-06-08 18:15:05 -070027import org.onosproject.net.flow.DefaultTrafficSelector;
alshabib0ccde6d2015-05-30 18:22:36 -070028import org.onosproject.net.flow.DefaultTrafficTreatment;
29import org.onosproject.net.flow.FlowRule;
30import org.onosproject.net.flow.FlowRuleOperations;
31import org.onosproject.net.flow.FlowRuleOperationsContext;
32import org.onosproject.net.flow.FlowRuleService;
33import org.onosproject.net.flow.TrafficSelector;
34import org.onosproject.net.flow.TrafficTreatment;
35import org.onosproject.net.flow.instructions.Instructions;
36import org.onosproject.net.flowobjective.FilteringObjective;
37import org.onosproject.net.flowobjective.ForwardingObjective;
38import org.onosproject.net.flowobjective.NextObjective;
39import org.onosproject.net.flowobjective.ObjectiveError;
40import org.slf4j.Logger;
41
42import static org.slf4j.LoggerFactory.getLogger;
43
44/**
45 * Simple single table pipeline abstraction.
46 */
47public class OLTPipeline extends AbstractHandlerBehaviour implements Pipeliner {
48
49 private final Logger log = getLogger(getClass());
50
51 private ServiceDirectory serviceDirectory;
52 private FlowRuleService flowRuleService;
53 private DeviceId deviceId;
54
alshabibb32cefe2015-06-08 18:15:05 -070055 private boolean done = false;
56
alshabib0ccde6d2015-05-30 18:22:36 -070057 @Override
58 public void init(DeviceId deviceId, PipelinerContext context) {
59 this.serviceDirectory = context.directory();
60 this.deviceId = deviceId;
61
62 flowRuleService = serviceDirectory.get(FlowRuleService.class);
alshabibb32cefe2015-06-08 18:15:05 -070063
64 }
65
66 private boolean installIGMPRule(ApplicationId appId, boolean done) {
67 if (done) {
68 return done;
69 }
70 TrafficSelector selector = DefaultTrafficSelector.builder()
71 .matchInPort(PortNumber.portNumber(1))
72 .matchEthType(Ethernet.TYPE_IPV4)
73 .matchIPProtocol((byte) 2).build();
74
75 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
76 .punt().build();
77
78 FlowRule rule = DefaultFlowRule.builder()
79 .forDevice(deviceId)
80 .fromApp(appId)
81 .withTreatment(treatment)
82 .withSelector(selector)
83 .makePermanent()
84 .withPriority(0)
85 .build();
86
87 FlowRuleOperations.Builder flowBuilder = FlowRuleOperations.builder();
88
89 flowRuleService.apply(flowBuilder.add(rule).build());
90
91 return true;
92
alshabib0ccde6d2015-05-30 18:22:36 -070093 }
94
95 @Override
96 public void filter(FilteringObjective filter) {
97 throw new UnsupportedOperationException("Single table does not filter.");
98 }
99
100 @Override
101 public void forward(ForwardingObjective fwd) {
alshabibb32cefe2015-06-08 18:15:05 -0700102 done = installIGMPRule(fwd.appId(), done);
alshabib0ccde6d2015-05-30 18:22:36 -0700103 FlowRuleOperations.Builder flowBuilder = FlowRuleOperations.builder();
104
105 if (fwd.flag() != ForwardingObjective.Flag.VERSATILE) {
106 throw new UnsupportedOperationException(
107 "Only VERSATILE is supported.");
108 }
109
110 boolean isPunt = fwd.treatment().immediate().stream().anyMatch(i -> {
111 if (i instanceof Instructions.OutputInstruction) {
112 Instructions.OutputInstruction out = (Instructions.OutputInstruction) i;
113 return out.port().equals(PortNumber.CONTROLLER);
114 }
115 return false;
116 });
117
118 if (isPunt) {
119 return;
120 }
121
122 TrafficSelector selector = fwd.selector();
123 TrafficTreatment treatment = fwd.treatment();
124 if ((fwd.treatment().deferred().size() == 0) &&
125 (fwd.treatment().immediate().size() == 0) &&
126 (fwd.treatment().tableTransition() == null) &&
127 (!fwd.treatment().clearedDeferred())) {
128 TrafficTreatment.Builder flowTreatment = DefaultTrafficTreatment.builder();
129 flowTreatment.add(Instructions.createDrop());
130 treatment = flowTreatment.build();
131 }
132
133 FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
134 .forDevice(deviceId)
135 .withSelector(selector)
136 .withTreatment(fwd.treatment())
137 .fromApp(fwd.appId())
138 .withPriority(fwd.priority());
139
140 if (fwd.permanent()) {
141 ruleBuilder.makePermanent();
142 } else {
143 ruleBuilder.makeTemporary(fwd.timeout());
144 }
145
146
147 switch (fwd.op()) {
148
149 case ADD:
150 flowBuilder.add(ruleBuilder.build());
151 break;
152 case REMOVE:
153 flowBuilder.remove(ruleBuilder.build());
154 break;
155 default:
156 log.warn("Unknown operation {}", fwd.op());
157 }
158
159 flowRuleService.apply(flowBuilder.build(new FlowRuleOperationsContext() {
160 @Override
161 public void onSuccess(FlowRuleOperations ops) {
162 if (fwd.context().isPresent()) {
163 fwd.context().get().onSuccess(fwd);
164 }
165 }
166
167 @Override
168 public void onError(FlowRuleOperations ops) {
169 if (fwd.context().isPresent()) {
170 fwd.context().get().onError(fwd, ObjectiveError.FLOWINSTALLATIONFAILED);
171 }
172 }
173 }));
174
175 }
176
177 @Override
178 public void next(NextObjective nextObjective) {
179 throw new UnsupportedOperationException("Single table does not next hop.");
180 }
181
182}