blob: e291be1dd859ba36a18d45ea6083def83846da2e [file] [log] [blame]
Michele Santuari9a8d16d2016-03-24 10:37:58 -07001/*
2 * Copyright 2014-2016 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.drivers.corsa;
17
18import org.onlab.packet.Ethernet;
19import org.onlab.packet.IPv4;
20import org.onlab.packet.MacAddress;
21import org.onlab.packet.VlanId;
22import org.onosproject.net.flow.DefaultFlowRule;
23import org.onosproject.net.flow.DefaultTrafficSelector;
24import org.onosproject.net.flow.DefaultTrafficTreatment;
25import org.onosproject.net.flow.FlowRule;
26import org.onosproject.net.flow.FlowRuleOperations;
27import org.onosproject.net.flow.TrafficSelector;
28import org.onosproject.net.flow.TrafficTreatment;
29import org.onosproject.net.flow.criteria.Criterion;
30import org.onosproject.net.flow.criteria.EthCriterion;
31import org.onosproject.net.flow.criteria.IPCriterion;
32import org.onosproject.net.flow.criteria.IPProtocolCriterion;
33import org.onosproject.net.flow.criteria.PortCriterion;
34import org.onosproject.net.flow.criteria.VlanIdCriterion;
35import org.onosproject.net.flowobjective.FilteringObjective;
36import org.onosproject.net.flowobjective.ForwardingObjective;
37import org.onosproject.net.flowobjective.ObjectiveError;
38import org.slf4j.Logger;
39
40import java.util.Collection;
41import java.util.Collections;
42
43import static org.slf4j.LoggerFactory.getLogger;
44
45/**
46 * OpenvSwitch emulation of the Corsa pipeline handler.
47 */
48public class OvsCorsaPipeline extends AbstractCorsaPipeline {
49
50 private final Logger log = getLogger(getClass());
51
52 protected static final int MAC_TABLE = 0;
53 protected static final int VLAN_MPLS_TABLE = 1;
54 protected static final int VLAN_TABLE = 2;
55 //protected static final int MPLS_TABLE = 3;
56 protected static final int ETHER_TABLE = 4;
57 protected static final int COS_MAP_TABLE = 5;
58 protected static final int FIB_TABLE = 6;
59 protected static final int LOCAL_TABLE = 9;
60
61 @Override
62 protected Collection<FlowRule> processArpTraffic(ForwardingObjective fwd, FlowRule.Builder rule) {
63 log.warn("Driver automatically handles ARP packets by punting to controller "
64 + " from ETHER table");
65 pass(fwd);
66 return Collections.emptyList();
67 }
68
69 @Override
70 protected Collection<FlowRule> processLinkDiscovery(ForwardingObjective fwd, FlowRule.Builder rule) {
71 log.warn("Driver currently does not currently handle LLDP packets");
72 fail(fwd, ObjectiveError.UNSUPPORTED);
73 return Collections.emptyList();
74 }
75
76 @Override
77 protected Collection<FlowRule> processIpTraffic(ForwardingObjective fwd, FlowRule.Builder rule) {
78 IPCriterion ipSrc = (IPCriterion) fwd.selector()
79 .getCriterion(Criterion.Type.IPV4_SRC);
80 if (ipSrc != null) {
81 log.warn("Driver does not currently handle matching Src IP");
82 fail(fwd, ObjectiveError.UNSUPPORTED);
83 return Collections.emptySet();
84 }
85 IPCriterion ipDst = (IPCriterion) fwd.selector()
86 .getCriterion(Criterion.Type.IPV4_DST);
87 if (ipDst != null) {
88 log.error("Driver handles Dst IP matching as specific forwarding "
89 + "objective, not versatile");
90 fail(fwd, ObjectiveError.UNSUPPORTED);
91 return Collections.emptySet();
92 }
93 IPProtocolCriterion ipProto = (IPProtocolCriterion) fwd.selector()
94 .getCriterion(Criterion.Type.IP_PROTO);
95 if (ipProto != null && ipProto.protocol() == IPv4.PROTOCOL_TCP) {
96 log.warn("Driver automatically punts all packets reaching the "
97 + "LOCAL table to the controller");
98 pass(fwd);
99 return Collections.emptySet();
100 }
101 return Collections.emptySet();
102 }
103
104 @Override
105 protected FlowRule.Builder processSpecificRoutingRule(FlowRule.Builder rb) {
106 return rb.forTable(FIB_TABLE);
107 }
108
109 @Override
110 protected FlowRule.Builder processIpFilter(FilteringObjective filt, IPCriterion ip, PortCriterion port) {
111 log.debug("adding rule for IP: {}", ip.ip());
112 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
113 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
114 selector.matchEthType(Ethernet.TYPE_IPV4);
115 selector.matchIPDst(ip.ip());
116 treatment.transition(LOCAL_TABLE);
117 return DefaultFlowRule.builder()
118 .withSelector(selector.build())
119 .withTreatment(treatment.build())
120 .withPriority(HIGHEST_PRIORITY)
121 .makePermanent()
122 .forTable(FIB_TABLE);
123 }
124
125 @Override
126 protected FlowRule.Builder processVlanFiler(FilteringObjective filt, VlanIdCriterion vlan, PortCriterion port) {
127 log.debug("adding rule for VLAN: {}", vlan.vlanId());
128 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
129 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
130 selector.matchVlanId(vlan.vlanId());
131 selector.matchInPort(port.port());
132 treatment.transition(ETHER_TABLE);
133 treatment.deferred().popVlan();
134 return DefaultFlowRule.builder()
135 .forDevice(deviceId)
136 .withSelector(selector.build())
137 .withTreatment(treatment.build())
138 .withPriority(CONTROLLER_PRIORITY)
139 .makePermanent()
140 .forTable(VLAN_TABLE);
141 }
142
143
144 protected FlowRule.Builder processEthFiler(FilteringObjective filt, EthCriterion eth, PortCriterion port) {
145 log.debug("adding rule for MAC: {}", eth.mac());
146 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
147 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
148 selector.matchEthDst(eth.mac());
149 treatment.transition(VLAN_MPLS_TABLE);
150 return DefaultFlowRule.builder()
151 .forDevice(deviceId)
152 .withSelector(selector.build())
153 .withTreatment(treatment.build())
154 .withPriority(CONTROLLER_PRIORITY)
155 .makePermanent()
156 .forTable(MAC_TABLE);
157 }
158
159 @Override
160 protected void initializePipeline() {
161 processMacTable(true);
162 processVlanMplsTable(true);
163 processVlanTable(true);
164 processEtherTable(true);
165 processCosTable(true);
166 processFibTable(true);
167 processLocalTable(true);
168 }
169
170 private void processMacTable(boolean install) {
171 TrafficSelector.Builder selector;
172 TrafficTreatment.Builder treatment;
173
174 // Bcast rule
175 selector = DefaultTrafficSelector.builder();
176 treatment = DefaultTrafficTreatment.builder();
177
178 selector.matchEthDst(MacAddress.BROADCAST);
179 treatment.transition(VLAN_MPLS_TABLE);
180
181 FlowRule rule = DefaultFlowRule.builder()
182 .forDevice(deviceId)
183 .withSelector(selector.build())
184 .withTreatment(treatment.build())
185 .withPriority(CONTROLLER_PRIORITY)
186 .fromApp(appId)
187 .makePermanent()
188 .forTable(MAC_TABLE).build();
189 processFlowRule(true, rule, "Provisioned mac table transition");
190
191 //Drop rule
192 processTableMissDrop(true, MAC_TABLE, "Provisioned mac table drop action");
193
194 }
195
196 protected void processVlanMplsTable(boolean install) {
197 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
198 TrafficTreatment.Builder treatment = DefaultTrafficTreatment
199 .builder();
200 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
201 FlowRule rule;
202
203 selector.matchVlanId(VlanId.ANY);
204 treatment.transition(VLAN_TABLE);
205
206 rule = DefaultFlowRule.builder()
207 .forDevice(deviceId)
208 .withSelector(selector.build())
209 .withTreatment(treatment.build())
210 .withPriority(CONTROLLER_PRIORITY)
211 .fromApp(appId)
212 .makePermanent()
213 .forTable(VLAN_MPLS_TABLE).build();
214
215 processFlowRule(true, rule, "Provisioned vlan/mpls table");
216 }
217
218 private void processVlanTable(boolean install) {
219 processTableMissDrop(true, VLAN_TABLE, "Provisioned vlan table");
220 }
221
222 private void processEtherTable(boolean install) {
223 TrafficSelector.Builder selector = DefaultTrafficSelector.builder()
224 .matchEthType(Ethernet.TYPE_ARP);
225 TrafficTreatment.Builder treatment = DefaultTrafficTreatment
226 .builder()
227 .punt();
228
229 FlowRule rule = DefaultFlowRule.builder()
230 .forDevice(deviceId)
231 .withSelector(selector.build())
232 .withTreatment(treatment.build())
233 .withPriority(CONTROLLER_PRIORITY)
234 .fromApp(appId)
235 .makePermanent()
236 .forTable(ETHER_TABLE).build();
237
238 processFlowRule(true, rule, "Provisioned ether table");
239 selector = DefaultTrafficSelector.builder()
240 .matchEthType(Ethernet.TYPE_IPV4);
241 treatment = DefaultTrafficTreatment.builder()
242 .transition(COS_MAP_TABLE);
243
244 rule = DefaultFlowRule.builder()
245 .forDevice(deviceId)
246 .withPriority(CONTROLLER_PRIORITY)
247 .withSelector(selector.build())
248 .withTreatment(treatment.build())
249 .fromApp(appId)
250 .makePermanent()
251 .forTable(ETHER_TABLE).build();
252 processFlowRule(true, rule, "Provisioned ether table");
253
254 //Drop rule
255 processTableMissDrop(true, VLAN_TABLE, "Provisioned ether table");
256
257 }
258
259 private void processCosTable(boolean install) {
260 TrafficTreatment.Builder treatment = DefaultTrafficTreatment
261 .builder()
262 .transition(FIB_TABLE);
263 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
264
265 FlowRule rule = DefaultFlowRule.builder()
266 .forDevice(deviceId)
267 .withSelector(selector.build())
268 .withTreatment(treatment.build())
269 .withPriority(DROP_PRIORITY)
270 .fromApp(appId)
271 .makePermanent()
272 .forTable(COS_MAP_TABLE).build();
273 processFlowRule(true, rule, "Provisioned cos table");
274
275 }
276
277 private void processFibTable(boolean install) {
278 processTableMissDrop(true, FIB_TABLE, "Provisioned FIB table");
279 }
280
281 private void processLocalTable(boolean install) {
282 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
283
284 TrafficTreatment.Builder treatment = DefaultTrafficTreatment
285 .builder()
286 .punt();
287
288 FlowRule rule = DefaultFlowRule.builder()
289 .forDevice(deviceId)
290 .withSelector(selector.build())
291 .withTreatment(treatment.build())
292 .withPriority(CONTROLLER_PRIORITY)
293 .fromApp(appId)
294 .makePermanent()
295 .forTable(LOCAL_TABLE).build();
296
297 processFlowRule(true, rule, "Provisioned Local table");
298 }
299
300
301}