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