blob: a551f798fdeeb6dcd2ca6749aed335f13346bbf1 [file] [log] [blame]
Thomas Vachuska83e090e2014-10-22 14:25:35 -07001/*
Ray Milkey34c95902015-04-15 09:47:53 -07002 * Copyright 2014-2015 Open Networking Laboratory
Thomas Vachuska83e090e2014-10-22 14:25:35 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * 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
Thomas Vachuska83e090e2014-10-22 14:25:35 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * 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.
Thomas Vachuska83e090e2014-10-22 14:25:35 -070015 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.net.flow;
alshabib1d4cace2014-09-13 19:16:26 -070017
Thomas Vachuskaf4df0052015-01-06 12:30:11 -080018import com.google.common.base.MoreObjects;
19import com.google.common.collect.ImmutableList;
alshabib346b5b32015-03-06 00:42:16 -080020import com.google.common.collect.Lists;
Jonathan Hart8ef6d3b2015-03-08 21:21:27 -070021import org.apache.commons.collections.ListUtils;
Pavlin Radoslavov855ea2d2014-10-30 15:32:39 -070022import org.onlab.packet.IpAddress;
alshabib010c31d2014-09-26 10:01:12 -070023import org.onlab.packet.MacAddress;
Michele Santuari4b6019e2014-12-19 11:31:45 +010024import org.onlab.packet.MplsLabel;
alshabib010c31d2014-09-26 10:01:12 -070025import org.onlab.packet.VlanId;
sangho8995ac52015-02-04 11:29:03 -080026import org.onosproject.core.GroupId;
Thomas Vachuskaf4df0052015-01-06 12:30:11 -080027import org.onosproject.net.PortNumber;
28import org.onosproject.net.flow.instructions.Instruction;
29import org.onosproject.net.flow.instructions.Instructions;
tom1679e182014-10-09 13:50:45 -070030
Brian O'Connor6b528132015-03-10 16:39:52 -070031import java.util.Collections;
Thomas Vachuskaf4df0052015-01-06 12:30:11 -080032import java.util.List;
33import java.util.Objects;
Yuta HIGUCHI2809bf32014-10-20 22:44:12 -070034
Ray Milkey42507352015-03-20 15:16:10 -070035import static com.google.common.base.Preconditions.checkNotNull;
36
tom9a693fd2014-10-03 11:32:19 -070037/**
38 * Default traffic treatment implementation.
39 */
alshabib7b2748f2014-09-16 20:21:11 -070040public final class DefaultTrafficTreatment implements TrafficTreatment {
alshabib1d4cace2014-09-13 19:16:26 -070041
alshabib346b5b32015-03-06 00:42:16 -080042 private final List<Instruction> immediate;
43 private final List<Instruction> deferred;
Jonathan Hart4a0ba562015-03-23 17:23:33 -070044 private final List<Instruction> all;
alshabib346b5b32015-03-06 00:42:16 -080045 private final Instructions.TableTypeTransition table;
46
47 private final boolean hasClear;
alshabib1d4cace2014-09-13 19:16:26 -070048
Brian O'Connor6b528132015-03-10 16:39:52 -070049 private static final DefaultTrafficTreatment EMPTY
50 = new DefaultTrafficTreatment(Collections.emptyList());
51
tom9a693fd2014-10-03 11:32:19 -070052 /**
53 * Creates a new traffic treatment from the specified list of instructions.
54 *
Jonathan Hart4a0ba562015-03-23 17:23:33 -070055 * @param immediate immediate instructions
tom9a693fd2014-10-03 11:32:19 -070056 */
Jonathan Hart4a0ba562015-03-23 17:23:33 -070057 private DefaultTrafficTreatment(List<Instruction> immediate) {
58 this.immediate = ImmutableList.copyOf(checkNotNull(immediate));
alshabib346b5b32015-03-06 00:42:16 -080059 this.deferred = ImmutableList.of();
Jonathan Hart4a0ba562015-03-23 17:23:33 -070060 this.all = this.immediate;
alshabib346b5b32015-03-06 00:42:16 -080061 this.hasClear = false;
62 this.table = null;
63 }
64
Jonathan Hart4a0ba562015-03-23 17:23:33 -070065 /**
66 * Creates a new traffic treatment from the specified list of instructions.
67 *
68 * @param deferred deferred instructions
69 * @param immediate immediate instructions
70 * @param table table transition instruction
71 * @param clear instruction to clear the deferred actions list
72 */
alshabib346b5b32015-03-06 00:42:16 -080073 private DefaultTrafficTreatment(List<Instruction> deferred,
74 List<Instruction> immediate,
75 Instructions.TableTypeTransition table,
76 boolean clear) {
Ray Milkey42507352015-03-20 15:16:10 -070077 this.immediate = ImmutableList.copyOf(checkNotNull(immediate));
78 this.deferred = ImmutableList.copyOf(checkNotNull(deferred));
Jonathan Hart4a0ba562015-03-23 17:23:33 -070079 this.all = ListUtils.union(this.immediate, this.deferred);
alshabib346b5b32015-03-06 00:42:16 -080080 this.table = table;
81 this.hasClear = clear;
82
alshabib1d4cace2014-09-13 19:16:26 -070083 }
84
85 @Override
alshabib346b5b32015-03-06 00:42:16 -080086 public List<Instruction> deferred() {
87 return deferred;
88 }
89
90 @Override
91 public List<Instruction> immediate() {
92 return immediate;
93 }
94
95 @Override
Jonathan Hart8ef6d3b2015-03-08 21:21:27 -070096 public List<Instruction> allInstructions() {
Jonathan Hart4a0ba562015-03-23 17:23:33 -070097 return all;
Jonathan Hart8ef6d3b2015-03-08 21:21:27 -070098 }
99
100 @Override
alshabib346b5b32015-03-06 00:42:16 -0800101 public Instructions.TableTypeTransition tableTransition() {
102 return table;
103 }
104
105 @Override
Jonathan Hart4a0ba562015-03-23 17:23:33 -0700106 public boolean clearedDeferred() {
alshabib346b5b32015-03-06 00:42:16 -0800107 return hasClear;
alshabib1d4cace2014-09-13 19:16:26 -0700108 }
109
110 /**
tom9a693fd2014-10-03 11:32:19 -0700111 * Returns a new traffic treatment builder.
112 *
113 * @return traffic treatment builder
114 */
115 public static TrafficTreatment.Builder builder() {
116 return new Builder();
117 }
118
Jonathan Hart6e88c682014-10-21 17:05:25 -0700119 /**
Brian O'Connor6b528132015-03-10 16:39:52 -0700120 * Returns an empty traffic treatment.
121 *
122 * @return empty traffic treatment
123 */
124 public static TrafficTreatment emptyTreatment() {
125 return EMPTY;
126 }
127
128 /**
Jonathan Hart6e88c682014-10-21 17:05:25 -0700129 * Returns a new traffic treatment builder primed to produce entities
130 * patterned after the supplied treatment.
131 *
Yuta HIGUCHI5c947272014-11-03 21:39:21 -0800132 * @param treatment base treatment
Jonathan Hart6e88c682014-10-21 17:05:25 -0700133 * @return traffic treatment builder
134 */
135 public static TrafficTreatment.Builder builder(TrafficTreatment treatment) {
136 return new Builder(treatment);
137 }
138
alshabib8ca53902014-10-07 13:11:17 -0700139 //FIXME: Order of instructions may affect hashcode
140 @Override
141 public int hashCode() {
alshabib346b5b32015-03-06 00:42:16 -0800142 return Objects.hash(immediate, deferred, table);
alshabib8ca53902014-10-07 13:11:17 -0700143 }
144
145 @Override
146 public boolean equals(Object obj) {
147 if (this == obj) {
148 return true;
149 }
150 if (obj instanceof DefaultTrafficTreatment) {
151 DefaultTrafficTreatment that = (DefaultTrafficTreatment) obj;
alshabib346b5b32015-03-06 00:42:16 -0800152 return Objects.equals(immediate, that.immediate) &&
153 Objects.equals(deferred, that.deferred) &&
154 Objects.equals(table, that.table);
alshabib8ca53902014-10-07 13:11:17 -0700155
156 }
157 return false;
158 }
159
Jonathan Hartd87aeca2014-10-21 10:42:52 -0700160 @Override
161 public String toString() {
162 return MoreObjects.toStringHelper(getClass())
alshabib346b5b32015-03-06 00:42:16 -0800163 .add("immediate", immediate)
164 .add("deferred", deferred)
165 .add("transition", table == null ? "None" : table.toString())
166 .add("cleared", hasClear)
Jonathan Hartd87aeca2014-10-21 10:42:52 -0700167 .toString();
168 }
169
tom9a693fd2014-10-03 11:32:19 -0700170 /**
alshabib1d4cace2014-09-13 19:16:26 -0700171 * Builds a list of treatments following the following order.
Thomas Vachuska4b420772014-10-30 16:46:17 -0700172 * Modifications -&gt; Group -&gt; Output (including drop)
alshabib1d4cace2014-09-13 19:16:26 -0700173 */
tom9a693fd2014-10-03 11:32:19 -0700174 public static final class Builder implements TrafficTreatment.Builder {
alshabib1d4cace2014-09-13 19:16:26 -0700175
alshabib346b5b32015-03-06 00:42:16 -0800176 boolean clear = false;
alshabib1d4cace2014-09-13 19:16:26 -0700177
alshabib346b5b32015-03-06 00:42:16 -0800178 Instructions.TableTypeTransition table;
alshabib1d4cace2014-09-13 19:16:26 -0700179
alshabib346b5b32015-03-06 00:42:16 -0800180 List<Instruction> deferred = Lists.newLinkedList();
181
182 List<Instruction> immediate = Lists.newLinkedList();
183
184 List<Instruction> current = immediate;
alshabib1d4cace2014-09-13 19:16:26 -0700185
tom9a693fd2014-10-03 11:32:19 -0700186 // Creates a new builder
187 private Builder() {
188 }
189
Jonathan Hart6e88c682014-10-21 17:05:25 -0700190 // Creates a new builder based off an existing treatment
191 private Builder(TrafficTreatment treatment) {
Jonathan Hart4a0ba562015-03-23 17:23:33 -0700192 deferred();
193 treatment.deferred().forEach(i -> add(i));
194
195 immediate();
196 treatment.immediate().forEach(i -> add(i));
197
198 clear = treatment.clearedDeferred();
Jonathan Hart6e88c682014-10-21 17:05:25 -0700199 }
200
alshabib8ca53902014-10-07 13:11:17 -0700201 @Override
alshabib1d4cace2014-09-13 19:16:26 -0700202 public Builder add(Instruction instruction) {
alshabib346b5b32015-03-06 00:42:16 -0800203
alshabib1d4cace2014-09-13 19:16:26 -0700204 switch (instruction.type()) {
tom9a693fd2014-10-03 11:32:19 -0700205 case DROP:
tom9a693fd2014-10-03 11:32:19 -0700206 case OUTPUT:
alshabib346b5b32015-03-06 00:42:16 -0800207 case GROUP:
Marc De Leenheer49087752014-10-23 13:54:09 -0700208 case L0MODIFICATION:
tom9a693fd2014-10-03 11:32:19 -0700209 case L2MODIFICATION:
210 case L3MODIFICATION:
alshabib346b5b32015-03-06 00:42:16 -0800211 current.add(instruction);
tom9a693fd2014-10-03 11:32:19 -0700212 break;
alshabib346b5b32015-03-06 00:42:16 -0800213 case TABLE:
214 table = (Instructions.TableTypeTransition) instruction;
tom9a693fd2014-10-03 11:32:19 -0700215 break;
216 default:
tom1679e182014-10-09 13:50:45 -0700217 throw new IllegalArgumentException("Unknown instruction type: " +
218 instruction.type());
alshabib1d4cace2014-09-13 19:16:26 -0700219 }
alshabib346b5b32015-03-06 00:42:16 -0800220
alshabib1d4cace2014-09-13 19:16:26 -0700221 return this;
222 }
223
224 @Override
Thomas Vachuskaf4df0052015-01-06 12:30:11 -0800225 public Builder drop() {
226 return add(Instructions.createDrop());
227 }
228
229 @Override
230 public Builder punt() {
231 return add(Instructions.createOutput(PortNumber.CONTROLLER));
alshabib010c31d2014-09-26 10:01:12 -0700232 }
233
234 @Override
235 public Builder setOutput(PortNumber number) {
236 return add(Instructions.createOutput(number));
237 }
238
239 @Override
240 public Builder setEthSrc(MacAddress addr) {
241 return add(Instructions.modL2Src(addr));
242 }
243
244 @Override
245 public Builder setEthDst(MacAddress addr) {
246 return add(Instructions.modL2Dst(addr));
247 }
248
249 @Override
250 public Builder setVlanId(VlanId id) {
251 return add(Instructions.modVlanId(id));
252 }
253
254 @Override
255 public Builder setVlanPcp(Byte pcp) {
256 return add(Instructions.modVlanPcp(pcp));
257 }
258
259 @Override
Pavlin Radoslavov855ea2d2014-10-30 15:32:39 -0700260 public Builder setIpSrc(IpAddress addr) {
alshabib010c31d2014-09-26 10:01:12 -0700261 return add(Instructions.modL3Src(addr));
262 }
263
264 @Override
Pavlin Radoslavov855ea2d2014-10-30 15:32:39 -0700265 public Builder setIpDst(IpAddress addr) {
alshabib010c31d2014-09-26 10:01:12 -0700266 return add(Instructions.modL3Dst(addr));
267 }
268
269 @Override
sangho3f97a17d2015-01-29 22:56:29 -0800270 public Builder decNwTtl() {
271 return add(Instructions.decNwTtl());
272 }
273
274 @Override
275 public Builder copyTtlIn() {
276 return add(Instructions.copyTtlIn());
277 }
278
279 @Override
280 public Builder copyTtlOut() {
281 return add(Instructions.copyTtlOut());
282 }
283
284 @Override
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800285 public Builder pushMpls() {
286 return add(Instructions.pushMpls());
287 }
288
289 @Override
290 public Builder popMpls() {
291 return add(Instructions.popMpls());
292 }
293
sangho3f97a17d2015-01-29 22:56:29 -0800294 @Override
Michele Santuari4b6019e2014-12-19 11:31:45 +0100295 public Builder popMpls(Short etherType) {
sangho3f97a17d2015-01-29 22:56:29 -0800296 return add(Instructions.popMpls(etherType));
297 }
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800298
299 @Override
Michele Santuari4b6019e2014-12-19 11:31:45 +0100300 public Builder setMpls(MplsLabel mplsLabel) {
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800301 return add(Instructions.modMplsLabel(mplsLabel));
302 }
303
304 @Override
sangho3f97a17d2015-01-29 22:56:29 -0800305 public Builder decMplsTtl() {
306 return add(Instructions.decMplsTtl());
307 }
308
309 @Override
Marc De Leenheer49087752014-10-23 13:54:09 -0700310 public Builder setLambda(short lambda) {
311 return add(Instructions.modL0Lambda(lambda));
312 }
313
314 @Override
sangho8995ac52015-02-04 11:29:03 -0800315 public Builder group(GroupId groupId) {
316 return add(Instructions.createGroup(groupId));
317 }
318
319 @Override
Saurav Dasfbe25c52015-03-04 11:12:00 -0800320 public Builder popVlan() {
321 return add(Instructions.popVlan());
322 }
323
324 @Override
Jonathan Hart54b406b2015-03-06 16:24:14 -0800325 public Builder pushVlan() {
326 return add(Instructions.pushVlan());
327 }
328
329 @Override
alshabib346b5b32015-03-06 00:42:16 -0800330 public Builder transition(FlowRule.Type type) {
alshabibd17abc22015-04-21 18:26:35 -0700331 return add(Instructions.transition(type.ordinal()));
332 }
333
334 @Override
335 public Builder transition(Integer tableId) {
336 return add(Instructions.transition(tableId));
alshabib346b5b32015-03-06 00:42:16 -0800337 }
338
339 @Override
340 public Builder immediate() {
341 current = immediate;
342 return this;
343 }
344
345 @Override
346 public Builder deferred() {
347 current = deferred;
348 return this;
349 }
350
351 @Override
352 public Builder wipeDeferred() {
353 clear = true;
354 return this;
355 }
356
357 @Override
alshabib1d4cace2014-09-13 19:16:26 -0700358 public TrafficTreatment build() {
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700359 //Don't add DROP instruction by default when instruction
360 //set is empty. This will be handled in DefaultSingleTablePipeline
361 //driver.
362
363 //if (deferred.size() == 0 && immediate.size() == 0
364 // && table == null && !clear) {
365 // drop();
366 //}
alshabib346b5b32015-03-06 00:42:16 -0800367 return new DefaultTrafficTreatment(deferred, immediate, table, clear);
alshabib1d4cace2014-09-13 19:16:26 -0700368 }
369
370 }
371
372}