blob: 581a734e6e10746ce0517920ca1157d2111e5fcf [file] [log] [blame]
Michele Santuari9a8d16d2016-03-24 10:37:58 -07001/*
2 * Copyright 2016-present 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.MacAddress;
20import org.onlab.packet.VlanId;
21import org.onosproject.net.flow.DefaultFlowRule;
22import org.onosproject.net.flow.DefaultTrafficSelector;
23import org.onosproject.net.flow.DefaultTrafficTreatment;
24import org.onosproject.net.flow.FlowRule;
25import org.onosproject.net.flow.TrafficSelector;
26import org.onosproject.net.flow.TrafficTreatment;
27import org.onosproject.net.flow.criteria.Criterion;
28import org.onosproject.net.flow.criteria.EthCriterion;
29import org.onosproject.net.flow.criteria.IPCriterion;
30import org.onosproject.net.flow.criteria.PortCriterion;
31import org.onosproject.net.flow.criteria.VlanIdCriterion;
32import org.onosproject.net.flow.instructions.L2ModificationInstruction;
33import org.onosproject.net.flowobjective.FilteringObjective;
34import org.onosproject.net.flowobjective.ForwardingObjective;
35import org.onosproject.net.meter.Band;
36import org.onosproject.net.meter.DefaultBand;
37import org.onosproject.net.meter.DefaultMeterRequest;
38import org.onosproject.net.meter.Meter;
39import org.onosproject.net.meter.MeterId;
40import org.onosproject.net.meter.MeterRequest;
41import org.slf4j.Logger;
42
43import java.util.Collection;
44import java.util.Collections;
45
46import static org.onosproject.net.flow.FlowRule.Builder;
47import static org.slf4j.LoggerFactory.getLogger;
48
49/**
50 * Implementation of the Corsa pipeline handler for pipeline version 3.
51 */
52public class CorsaPipelineV3 extends AbstractCorsaPipeline {
53
54 private final Logger log = getLogger(getClass());
55
56 protected static final int PORT_BASED_PROTO_TABLE = 0;
57 protected static final int VLAN_CHECK_TABLE = 1;
58 protected static final int VLAN_MAC_XLATE_TABLE = 2;
59 protected static final int VLAN_CIRCUIT_TABLE = 3;
60 protected static final int PRIORITY_MAP_TABLE = 4;
61 protected static final int L3_IF_MAC_DA_TABLE = 5;
62 protected static final int ETHER_TABLE = 6;
63 protected static final int FIB_TABLE = 7;
64 protected static final int LOCAL_TABLE = 9;
65
66 protected static final byte MAX_VLAN_PCP = 7;
67
68 protected MeterId defaultMeterId = null;
69
70 @Override
71 protected TrafficTreatment processNextTreatment(TrafficTreatment treatment) {
72 TrafficTreatment.Builder tb = DefaultTrafficTreatment.builder();
73
74 treatment.immediate().stream()
75 .filter(i -> {
76 switch (i.type()) {
77 case L2MODIFICATION:
78 L2ModificationInstruction l2i = (L2ModificationInstruction) i;
79 if (l2i instanceof L2ModificationInstruction.ModVlanIdInstruction ||
80 l2i instanceof L2ModificationInstruction.ModEtherInstruction) {
81 return true;
82 }
83 case OUTPUT:
84 return true;
85 default:
86 return false;
87 }
88 }).forEach(i -> tb.add(i));
89 return tb.build();
90 }
91
92 @Override
93 protected TrafficTreatment.Builder processSpecificRoutingTreatment() {
94 return DefaultTrafficTreatment.builder().deferred();
95 }
96
97 @Override
98 protected Builder processSpecificRoutingRule(Builder rb) {
99 return rb.forTable(FIB_TABLE);
100 }
101
102 @Override
103 protected Collection<FlowRule> processSpecificSwitch(ForwardingObjective fwd) {
104 TrafficSelector filteredSelector =
105 DefaultTrafficSelector.builder()
106 .matchInPort(
107 ((PortCriterion) fwd.selector().getCriterion(Criterion.Type.IN_PORT)).port())
108 .matchVlanId(
109 ((VlanIdCriterion) fwd.selector().getCriterion(Criterion.Type.VLAN_VID)).vlanId())
110 .build();
111
112 Builder ruleBuilder = DefaultFlowRule.builder()
113 .fromApp(fwd.appId())
114 .withPriority(fwd.priority())
115 .forDevice(deviceId)
116 .withSelector(filteredSelector)
117 .withTreatment(fwd.treatment())
118 .forTable(VLAN_CIRCUIT_TABLE);
119
120 if (fwd.permanent()) {
121 ruleBuilder.makePermanent();
122 } else {
123 ruleBuilder.makeTemporary(fwd.timeout());
124 }
125
126 return Collections.singletonList(ruleBuilder.build());
127 }
128
129 @Override
130 protected Collection<FlowRule> processArpTraffic(ForwardingObjective fwd, Builder rule) {
131 //TODO
132 return Collections.emptyList();
133 }
134
135 @Override
136 protected Collection<FlowRule> processLinkDiscovery(ForwardingObjective fwd, Builder rule) {
137 //TODO
138 return Collections.emptyList();
139 }
140
141 @Override
142 protected Collection<FlowRule> processIpTraffic(ForwardingObjective fwd, Builder rule) {
143 //TODO
144 return Collections.emptyList();
145 }
146
147 @Override
148 protected Builder processEthFiler(FilteringObjective filt, EthCriterion eth, PortCriterion port) {
149 log.debug("adding rule for MAC: {}", eth.mac());
150 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
151 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
152 selector.matchEthDst(eth.mac());
153 selector.matchInPort(port.port());
154 treatment.transition(ETHER_TABLE);
155 return DefaultFlowRule.builder()
156 .withSelector(selector.build())
157 .withTreatment(treatment.build())
158 .withPriority(CONTROLLER_PRIORITY)
159 .makePermanent()
160 .forTable(L3_IF_MAC_DA_TABLE);
161 }
162
163 @Override
164 protected Builder processVlanFiler(FilteringObjective filt, VlanIdCriterion vlan, PortCriterion port) {
165 log.debug("adding rule for VLAN: {}", vlan.vlanId());
166 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
167 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
168 selector.matchVlanId(vlan.vlanId());
169 selector.matchInPort(port.port());
170 /* Static treatment for VLAN_CIRCUIT_TABLE */
171 treatment.setVlanPcp(MAX_VLAN_PCP);
172 treatment.setQueue(0);
173 treatment.meter(MeterId.meterId(defaultMeterId.id())); /* use default meter (Green) */
174 treatment.transition(L3_IF_MAC_DA_TABLE);
175 return DefaultFlowRule.builder()
176 .withSelector(selector.build())
177 .withTreatment(treatment.build())
178 .withPriority(CONTROLLER_PRIORITY)
179 .makePermanent()
180 .forTable(VLAN_CIRCUIT_TABLE);
181 }
182
183 @Override
184 protected Builder processIpFilter(FilteringObjective filt, IPCriterion ip, PortCriterion port) {
185 log.debug("adding rule for IP: {}", ip.ip());
186 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
187 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
188 selector.matchEthType(Ethernet.TYPE_IPV4);
189 selector.matchIPDst(ip.ip());
190 treatment.transition(LOCAL_TABLE);
191 return DefaultFlowRule.builder()
192 .withSelector(selector.build())
193 .withTreatment(treatment.build())
194 .withPriority(HIGHEST_PRIORITY)
195 .makePermanent()
196 .forTable(FIB_TABLE);
197 }
198
199 @Override
200 public void initializePipeline() {
201 processMeterTable(true);
202 processPortBasedProtoTable(true); /* Table 0 */
203 processVlanCheckTable(true); /* Table 1 */
204 processVlanMacXlateTable(true); /* Table 2 */
205 processVlanCircuitTable(true); /* Table 3 */
206 processPriorityMapTable(true); /* Table 4 */
207 processL3IFMacDATable(true); /* Table 5 */
208 processEtherTable(true); /* Table 6 */
209 processFibTable(true); /* Table 7 */
210 processLocalTable(true); /* Table 9 */
211 }
212
213 protected void processMeterTable(boolean install) {
214 //Green meter : Pass all traffic
215 Band dropBand = DefaultBand.builder()
216 .ofType(Band.Type.DROP)
217 .withRate(0xFFFFFFFF) /* Max Rate */
218 .build();
219 MeterRequest.Builder ops = DefaultMeterRequest.builder()
220 .forDevice(deviceId)
221 .withBands(Collections.singletonList(dropBand))
222 .fromApp(appId);
223
224 Meter meter = meterService.submit(install ? ops.add() : ops.remove());
225 defaultMeterId = meter.id();
226 }
227
228 protected void processPortBasedProtoTable(boolean install) {
229 /* Default action */
230 processTableMissGoTo(install, PORT_BASED_PROTO_TABLE, VLAN_CHECK_TABLE, "Provisioned port-based table");
231 }
232
233 protected void processVlanCheckTable(boolean install) {
234
235 /* Default action */
236 processTableMissDrop(install, VLAN_CHECK_TABLE, "Provisioned vlantable drop");
237
238 processTaggedPackets(install);
239
240 }
241
242 /* Tagged packets to VLAN_MAC_XLATE */
243 protected void processTaggedPackets(boolean install) {
244 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
245 selector.matchVlanId(VlanId.ANY);
246
247 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
248 treatment.transition(VLAN_MAC_XLATE_TABLE);
249
250 FlowRule rule = DefaultFlowRule.builder()
251 .forDevice(deviceId)
252 .withSelector(selector.build())
253 .withTreatment(treatment.build())
254 .withPriority(CONTROLLER_PRIORITY)
255 .fromApp(appId)
256 .makePermanent()
257 .forTable(VLAN_CHECK_TABLE).build();
258 processFlowRule(install, rule, "Provisioned vlan table tagged packets");
259 }
260
261 protected void processVlanMacXlateTable(boolean install) {
262 /* Default action */
263 processTableMissGoTo(install, VLAN_MAC_XLATE_TABLE, VLAN_CIRCUIT_TABLE, "Provisioned vlan mac table");
264 }
265
266 protected void processVlanCircuitTable(boolean install) {
267 /* Default action */
268 processTableMissDrop(install, VLAN_CIRCUIT_TABLE, "Provisioned vlan circuit");
269 }
270
271 private void processPriorityMapTable(boolean install) {
272 /* Not required currently */
273 }
274
275 protected void processL3IFMacDATable(boolean install) {
276 int table = L3_IF_MAC_DA_TABLE;
277
278 /* Default action */
279 processTableMissDrop(install, table, "Provisioned l3 table drop");
280
281 /* Allow MAC broadcast frames on all ports */
282 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
283 selector.matchEthDst(MacAddress.BROADCAST);
284
285 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
286 treatment.transition(ETHER_TABLE);
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(table).build();
296 processFlowRule(install, rule, "Provisioned l3 table");
297 }
298
299
300 protected void processEtherTable(boolean install) {
301 int table = ETHER_TABLE;
302
303 /* Default action */
304 processTableMissDrop(install, table, "Provisioned ether type table drop");
305
306 /* Arp to controller */
307 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
308 selector.matchEthType(Ethernet.TYPE_ARP);
309
310 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
311 treatment.punt();
312
313 FlowRule rule = DefaultFlowRule.builder()
314 .forDevice(deviceId)
315 .withSelector(selector.build())
316 .withTreatment(treatment.build())
317 .withPriority(CONTROLLER_PRIORITY)
318 .fromApp(appId)
319 .makePermanent()
320 .forTable(table).build();
321 processFlowRule(install, rule, "Provisioned ether type table arp");
322
323 /* IP to FIB_TABLE */
324 selector = DefaultTrafficSelector.builder();
325 selector.matchEthType(Ethernet.TYPE_IPV4);
326
327 treatment = DefaultTrafficTreatment.builder();
328 treatment.transition(FIB_TABLE);
329
330 rule = DefaultFlowRule.builder()
331 .forDevice(deviceId)
332 .withSelector(selector.build())
333 .withTreatment(treatment.build())
334 .withPriority(CONTROLLER_PRIORITY)
335 .fromApp(appId)
336 .makePermanent()
337 .forTable(table).build();
338 processFlowRule(install, rule, "Provisioned ether type table ip");
339 }
340
341 private void processFibTable(boolean install) {
342 /* Default action */
343 processTableMissDrop(install, FIB_TABLE, "Provisioned fib drop");
344 }
345
346 private void processLocalTable(boolean install) {
347 int table = LOCAL_TABLE;
348 /* Default action */
349 processTableMissDrop(install, table, "Provisioned local table drop");
350
351 /* Send all protocols to controller */
352 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
353
354 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
355 treatment.punt();
356
357 FlowRule rule = DefaultFlowRule.builder()
358 .forDevice(deviceId)
359 .withSelector(selector.build())
360 .withTreatment(treatment.build())
361 .withPriority(CONTROLLER_PRIORITY)
362 .fromApp(appId)
363 .makePermanent()
364 .forTable(table).build();
365 processFlowRule(install, rule, "Provisioned ether type table to controller");
366 }
367
368
369}