blob: 499e9e7d8eff57e8b2dccf2226833ad640cd87a8 [file] [log] [blame]
Thomas Vachuska83e090e2014-10-22 14:25:35 -07001/*
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07002 * Copyright 2014 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;
Pavlin Radoslavov855ea2d2014-10-30 15:32:39 -070021import org.onlab.packet.IpAddress;
alshabib010c31d2014-09-26 10:01:12 -070022import org.onlab.packet.MacAddress;
Michele Santuari4b6019e2014-12-19 11:31:45 +010023import org.onlab.packet.MplsLabel;
alshabib010c31d2014-09-26 10:01:12 -070024import org.onlab.packet.VlanId;
sangho8995ac52015-02-04 11:29:03 -080025import org.onosproject.core.GroupId;
Thomas Vachuskaf4df0052015-01-06 12:30:11 -080026import org.onosproject.net.PortNumber;
27import org.onosproject.net.flow.instructions.Instruction;
28import org.onosproject.net.flow.instructions.Instructions;
tom1679e182014-10-09 13:50:45 -070029
Thomas Vachuskaf4df0052015-01-06 12:30:11 -080030import java.util.List;
31import java.util.Objects;
Yuta HIGUCHI2809bf32014-10-20 22:44:12 -070032
tom9a693fd2014-10-03 11:32:19 -070033/**
34 * Default traffic treatment implementation.
35 */
alshabib7b2748f2014-09-16 20:21:11 -070036public final class DefaultTrafficTreatment implements TrafficTreatment {
alshabib1d4cace2014-09-13 19:16:26 -070037
alshabib346b5b32015-03-06 00:42:16 -080038 private final List<Instruction> immediate;
39 private final List<Instruction> deferred;
40 private final Instructions.TableTypeTransition table;
41
42 private final boolean hasClear;
alshabib1d4cace2014-09-13 19:16:26 -070043
tom9a693fd2014-10-03 11:32:19 -070044 /**
45 * Creates a new traffic treatment from the specified list of instructions.
46 *
47 * @param instructions treatment instructions
48 */
alshabib7b2748f2014-09-16 20:21:11 -070049 private DefaultTrafficTreatment(List<Instruction> instructions) {
alshabib346b5b32015-03-06 00:42:16 -080050 this.immediate = ImmutableList.copyOf(instructions);
51 this.deferred = ImmutableList.of();
52 this.hasClear = false;
53 this.table = null;
54 }
55
56 private DefaultTrafficTreatment(List<Instruction> deferred,
57 List<Instruction> immediate,
58 Instructions.TableTypeTransition table,
59 boolean clear) {
60 this.immediate = ImmutableList.copyOf(immediate);
61 this.deferred = ImmutableList.copyOf(deferred);
62 this.table = table;
63 this.hasClear = clear;
64
alshabib1d4cace2014-09-13 19:16:26 -070065 }
66
67 @Override
68 public List<Instruction> instructions() {
alshabib346b5b32015-03-06 00:42:16 -080069 return immediate;
70 }
71
72 @Override
73 public List<Instruction> deferred() {
74 return deferred;
75 }
76
77 @Override
78 public List<Instruction> immediate() {
79 return immediate;
80 }
81
82 @Override
83 public Instructions.TableTypeTransition tableTransition() {
84 return table;
85 }
86
87 @Override
88 public Boolean clearedDeferred() {
89 return hasClear;
alshabib1d4cace2014-09-13 19:16:26 -070090 }
91
92 /**
tom9a693fd2014-10-03 11:32:19 -070093 * Returns a new traffic treatment builder.
94 *
95 * @return traffic treatment builder
96 */
97 public static TrafficTreatment.Builder builder() {
98 return new Builder();
99 }
100
Jonathan Hart6e88c682014-10-21 17:05:25 -0700101 /**
102 * Returns a new traffic treatment builder primed to produce entities
103 * patterned after the supplied treatment.
104 *
Yuta HIGUCHI5c947272014-11-03 21:39:21 -0800105 * @param treatment base treatment
Jonathan Hart6e88c682014-10-21 17:05:25 -0700106 * @return traffic treatment builder
107 */
108 public static TrafficTreatment.Builder builder(TrafficTreatment treatment) {
109 return new Builder(treatment);
110 }
111
alshabib8ca53902014-10-07 13:11:17 -0700112 //FIXME: Order of instructions may affect hashcode
113 @Override
114 public int hashCode() {
alshabib346b5b32015-03-06 00:42:16 -0800115 return Objects.hash(immediate, deferred, table);
alshabib8ca53902014-10-07 13:11:17 -0700116 }
117
118 @Override
119 public boolean equals(Object obj) {
120 if (this == obj) {
121 return true;
122 }
123 if (obj instanceof DefaultTrafficTreatment) {
124 DefaultTrafficTreatment that = (DefaultTrafficTreatment) obj;
alshabib346b5b32015-03-06 00:42:16 -0800125 return Objects.equals(immediate, that.immediate) &&
126 Objects.equals(deferred, that.deferred) &&
127 Objects.equals(table, that.table);
alshabib8ca53902014-10-07 13:11:17 -0700128
129 }
130 return false;
131 }
132
Jonathan Hartd87aeca2014-10-21 10:42:52 -0700133 @Override
134 public String toString() {
135 return MoreObjects.toStringHelper(getClass())
alshabib346b5b32015-03-06 00:42:16 -0800136 .add("immediate", immediate)
137 .add("deferred", deferred)
138 .add("transition", table == null ? "None" : table.toString())
139 .add("cleared", hasClear)
Jonathan Hartd87aeca2014-10-21 10:42:52 -0700140 .toString();
141 }
142
tom9a693fd2014-10-03 11:32:19 -0700143 /**
alshabib1d4cace2014-09-13 19:16:26 -0700144 * Builds a list of treatments following the following order.
Thomas Vachuska4b420772014-10-30 16:46:17 -0700145 * Modifications -&gt; Group -&gt; Output (including drop)
alshabib1d4cace2014-09-13 19:16:26 -0700146 */
tom9a693fd2014-10-03 11:32:19 -0700147 public static final class Builder implements TrafficTreatment.Builder {
alshabib1d4cace2014-09-13 19:16:26 -0700148
alshabib030111e2014-09-15 15:56:42 -0700149 boolean drop = false;
150
alshabib346b5b32015-03-06 00:42:16 -0800151 boolean clear = false;
alshabib1d4cace2014-09-13 19:16:26 -0700152
alshabib346b5b32015-03-06 00:42:16 -0800153 Instructions.TableTypeTransition table;
alshabib1d4cace2014-09-13 19:16:26 -0700154
alshabib346b5b32015-03-06 00:42:16 -0800155 List<Instruction> deferred = Lists.newLinkedList();
156
157 List<Instruction> immediate = Lists.newLinkedList();
158
159 List<Instruction> current = immediate;
alshabib1d4cace2014-09-13 19:16:26 -0700160
tom9a693fd2014-10-03 11:32:19 -0700161 // Creates a new builder
162 private Builder() {
163 }
164
Jonathan Hart6e88c682014-10-21 17:05:25 -0700165 // Creates a new builder based off an existing treatment
alshabib346b5b32015-03-06 00:42:16 -0800166 //FIXME only works for immediate instruction sets.
Jonathan Hart6e88c682014-10-21 17:05:25 -0700167 private Builder(TrafficTreatment treatment) {
168 for (Instruction instruction : treatment.instructions()) {
169 add(instruction);
170 }
171 }
172
alshabib8ca53902014-10-07 13:11:17 -0700173 @Override
alshabib1d4cace2014-09-13 19:16:26 -0700174 public Builder add(Instruction instruction) {
alshabib346b5b32015-03-06 00:42:16 -0800175
alshabib1d4cace2014-09-13 19:16:26 -0700176 switch (instruction.type()) {
tom9a693fd2014-10-03 11:32:19 -0700177 case DROP:
tom9a693fd2014-10-03 11:32:19 -0700178 case OUTPUT:
alshabib346b5b32015-03-06 00:42:16 -0800179 case GROUP:
Marc De Leenheer49087752014-10-23 13:54:09 -0700180 case L0MODIFICATION:
tom9a693fd2014-10-03 11:32:19 -0700181 case L2MODIFICATION:
182 case L3MODIFICATION:
alshabib346b5b32015-03-06 00:42:16 -0800183 current.add(instruction);
tom9a693fd2014-10-03 11:32:19 -0700184 break;
alshabib346b5b32015-03-06 00:42:16 -0800185 case TABLE:
186 table = (Instructions.TableTypeTransition) instruction;
tom9a693fd2014-10-03 11:32:19 -0700187 break;
188 default:
tom1679e182014-10-09 13:50:45 -0700189 throw new IllegalArgumentException("Unknown instruction type: " +
190 instruction.type());
alshabib346b5b32015-03-06 00:42:16 -0800191
192
alshabib1d4cace2014-09-13 19:16:26 -0700193 }
alshabib346b5b32015-03-06 00:42:16 -0800194
alshabib1d4cace2014-09-13 19:16:26 -0700195 return this;
196 }
197
198 @Override
Thomas Vachuskaf4df0052015-01-06 12:30:11 -0800199 public Builder drop() {
200 return add(Instructions.createDrop());
201 }
202
203 @Override
204 public Builder punt() {
205 return add(Instructions.createOutput(PortNumber.CONTROLLER));
alshabib010c31d2014-09-26 10:01:12 -0700206 }
207
208 @Override
209 public Builder setOutput(PortNumber number) {
210 return add(Instructions.createOutput(number));
211 }
212
213 @Override
214 public Builder setEthSrc(MacAddress addr) {
215 return add(Instructions.modL2Src(addr));
216 }
217
218 @Override
219 public Builder setEthDst(MacAddress addr) {
220 return add(Instructions.modL2Dst(addr));
221 }
222
223 @Override
224 public Builder setVlanId(VlanId id) {
225 return add(Instructions.modVlanId(id));
226 }
227
228 @Override
229 public Builder setVlanPcp(Byte pcp) {
230 return add(Instructions.modVlanPcp(pcp));
231 }
232
alshabibab21b2d2015-03-04 18:35:33 -0800233 public Builder stripVlan() {
234 return add(Instructions.stripVlanId());
235 }
236
alshabib010c31d2014-09-26 10:01:12 -0700237 @Override
Pavlin Radoslavov855ea2d2014-10-30 15:32:39 -0700238 public Builder setIpSrc(IpAddress addr) {
alshabib010c31d2014-09-26 10:01:12 -0700239 return add(Instructions.modL3Src(addr));
240 }
241
242 @Override
Pavlin Radoslavov855ea2d2014-10-30 15:32:39 -0700243 public Builder setIpDst(IpAddress addr) {
alshabib010c31d2014-09-26 10:01:12 -0700244 return add(Instructions.modL3Dst(addr));
245 }
246
247 @Override
sangho3f97a17d2015-01-29 22:56:29 -0800248 public Builder decNwTtl() {
249 return add(Instructions.decNwTtl());
250 }
251
252 @Override
253 public Builder copyTtlIn() {
254 return add(Instructions.copyTtlIn());
255 }
256
257 @Override
258 public Builder copyTtlOut() {
259 return add(Instructions.copyTtlOut());
260 }
261
262 @Override
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800263 public Builder pushMpls() {
264 return add(Instructions.pushMpls());
265 }
266
267 @Override
268 public Builder popMpls() {
269 return add(Instructions.popMpls());
270 }
271
sangho3f97a17d2015-01-29 22:56:29 -0800272 @Override
Michele Santuari4b6019e2014-12-19 11:31:45 +0100273 public Builder popMpls(Short etherType) {
sangho3f97a17d2015-01-29 22:56:29 -0800274 return add(Instructions.popMpls(etherType));
275 }
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800276
277 @Override
Michele Santuari4b6019e2014-12-19 11:31:45 +0100278 public Builder setMpls(MplsLabel mplsLabel) {
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800279 return add(Instructions.modMplsLabel(mplsLabel));
280 }
281
282 @Override
sangho3f97a17d2015-01-29 22:56:29 -0800283 public Builder decMplsTtl() {
284 return add(Instructions.decMplsTtl());
285 }
286
287 @Override
Marc De Leenheer49087752014-10-23 13:54:09 -0700288 public Builder setLambda(short lambda) {
289 return add(Instructions.modL0Lambda(lambda));
290 }
291
292 @Override
sangho8995ac52015-02-04 11:29:03 -0800293 public Builder group(GroupId groupId) {
294 return add(Instructions.createGroup(groupId));
295 }
296
297 @Override
Saurav Dasfbe25c52015-03-04 11:12:00 -0800298 public Builder popVlan() {
299 return add(Instructions.popVlan());
300 }
301
302 @Override
Jonathan Hart54b406b2015-03-06 16:24:14 -0800303 public Builder pushVlan() {
304 return add(Instructions.pushVlan());
305 }
306
307 @Override
alshabib346b5b32015-03-06 00:42:16 -0800308 public Builder transition(FlowRule.Type type) {
309 return add(Instructions.transition(type));
310 }
311
312 @Override
313 public Builder immediate() {
314 current = immediate;
315 return this;
316 }
317
318 @Override
319 public Builder deferred() {
320 current = deferred;
321 return this;
322 }
323
324 @Override
325 public Builder wipeDeferred() {
326 clear = true;
327 return this;
328 }
329
330 @Override
alshabib1d4cace2014-09-13 19:16:26 -0700331 public TrafficTreatment build() {
alshabib346b5b32015-03-06 00:42:16 -0800332 if (deferred.size() == 0 && immediate.size() == 0
333 && table == null && !clear) {
334 drop();
alshabib030111e2014-09-15 15:56:42 -0700335 }
alshabib346b5b32015-03-06 00:42:16 -0800336 return new DefaultTrafficTreatment(deferred, immediate, table, clear);
alshabib1d4cace2014-09-13 19:16:26 -0700337 }
338
339 }
340
341}