blob: f944f4b4c25b41d199c9769da5dedbd78fe13607 [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;
alshabib7b2748f2014-09-16 20:21:11 -070017
Brian O'Connorabafb502014-12-02 22:26:20 -080018import org.onosproject.core.ApplicationId;
19import org.onosproject.core.DefaultGroupId;
20import org.onosproject.core.GroupId;
21import org.onosproject.net.DeviceId;
alshabib7b2748f2014-09-16 20:21:11 -070022
Jonathan Hart8ef6d3b2015-03-08 21:21:27 -070023import java.util.Objects;
24
25import static com.google.common.base.MoreObjects.toStringHelper;
alshabibdb774072015-04-20 13:13:51 -070026import static com.google.common.base.Preconditions.checkArgument;
27import static com.google.common.base.Preconditions.checkNotNull;
Jonathan Hart8ef6d3b2015-03-08 21:21:27 -070028
alshabib7b2748f2014-09-16 20:21:11 -070029public class DefaultFlowRule implements FlowRule {
30
Ayaka Koshibed4e53e12014-09-18 14:24:55 -070031 private final DeviceId deviceId;
32 private final int priority;
alshabib7b2748f2014-09-16 20:21:11 -070033 private final TrafficSelector selector;
34 private final TrafficTreatment treatment;
Ayaka Koshibed4e53e12014-09-18 14:24:55 -070035 private final long created;
36
alshabib219ebaa2014-09-22 15:41:24 -070037 private final FlowId id;
Ayaka Koshibed4e53e12014-09-18 14:24:55 -070038
alshabibdb774072015-04-20 13:13:51 -070039 private final Short appId;
alshabiba68eb962014-09-24 20:34:13 -070040
alshabibba5ac482014-10-02 17:15:20 -070041 private final int timeout;
Jonathan Hartbc4a7932014-10-21 11:46:00 -070042 private final boolean permanent;
Sho SHIMIZU75a5bd92014-11-25 11:22:56 -080043 private final GroupId groupId;
alshabib6eb438a2014-10-01 16:39:37 -070044
alshabibdb774072015-04-20 13:13:51 -070045 private final Integer tableId;
sangho11c30ac2015-01-22 14:30:55 -080046
alshabib1c319ff2014-10-04 20:29:09 -070047
alshabibdb774072015-04-20 13:13:51 -070048 @Deprecated
alshabib97044902014-09-18 14:52:16 -070049 public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
alshabib1c319ff2014-10-04 20:29:09 -070050 TrafficTreatment treatment, int priority, long flowId,
Jonathan Hartbc4a7932014-10-21 11:46:00 -070051 int timeout, boolean permanent) {
alshabib6b5cfec2014-09-18 17:42:18 -070052 this.deviceId = deviceId;
53 this.priority = priority;
54 this.selector = selector;
55 this.treatment = treatment;
alshabib1c319ff2014-10-04 20:29:09 -070056 this.timeout = timeout;
Jonathan Hartbc4a7932014-10-21 11:46:00 -070057 this.permanent = permanent;
alshabib1c319ff2014-10-04 20:29:09 -070058 this.created = System.currentTimeMillis();
59
alshabib92c65ad2014-10-08 21:56:05 -070060 this.appId = (short) (flowId >>> 48);
Sho SHIMIZU75a5bd92014-11-25 11:22:56 -080061 this.groupId = new DefaultGroupId((short) ((flowId >>> 32) & 0xFFFF));
alshabib6b5cfec2014-09-18 17:42:18 -070062 this.id = FlowId.valueOf(flowId);
alshabibdb774072015-04-20 13:13:51 -070063 this.tableId = 0;
alshabib97044902014-09-18 14:52:16 -070064 }
65
alshabibdb774072015-04-20 13:13:51 -070066 @Deprecated
alshabiba7f7ca82014-09-22 11:41:23 -070067 public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
Saurav Dasfa2fa932015-03-03 11:29:48 -080068 TrafficTreatment treatment, int priority, long flowId,
69 int timeout, boolean permanent, Type tableType) {
70 this.deviceId = deviceId;
71 this.priority = priority;
72 this.selector = selector;
73 this.treatment = treatment;
74 this.timeout = timeout;
75 this.permanent = permanent;
76 this.created = System.currentTimeMillis();
77
78 this.appId = (short) (flowId >>> 48);
79 this.groupId = new DefaultGroupId((short) ((flowId >>> 32) & 0xFFFF));
80 this.id = FlowId.valueOf(flowId);
alshabib08d98982015-04-21 16:25:50 -070081 this.tableId = tableType.ordinal();
alshabibdb774072015-04-20 13:13:51 -070082
Saurav Dasfa2fa932015-03-03 11:29:48 -080083 }
84
alshabibdb774072015-04-20 13:13:51 -070085 @Deprecated
Saurav Dasfa2fa932015-03-03 11:29:48 -080086 public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
alshabib28204e52014-11-12 18:29:45 -080087 TrafficTreatment treatment, int priority, ApplicationId appId,
88 int timeout, boolean permanent) {
sangho11c30ac2015-01-22 14:30:55 -080089 this(deviceId, selector, treatment, priority, appId, new DefaultGroupId(0),
90 timeout, permanent);
91 }
92
alshabibdb774072015-04-20 13:13:51 -070093 @Deprecated
sangho11c30ac2015-01-22 14:30:55 -080094 public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
95 TrafficTreatment treatment, int priority, ApplicationId appId,
96 int timeout, boolean permanent, Type type) {
97
98 if (priority < FlowRule.MIN_PRIORITY) {
99 throw new IllegalArgumentException("Priority cannot be less than " + MIN_PRIORITY);
100 }
101
102 this.deviceId = deviceId;
103 this.priority = priority;
104 this.selector = selector;
105 this.treatment = treatment;
106 this.appId = appId.id();
107 this.groupId = new DefaultGroupId(0);
108 this.timeout = timeout;
109 this.permanent = permanent;
110 this.created = System.currentTimeMillis();
alshabib08d98982015-04-21 16:25:50 -0700111 this.tableId = type.ordinal();
sangho11c30ac2015-01-22 14:30:55 -0800112
113 /*
114 * id consists of the following.
115 * | appId (16 bits) | groupId (16 bits) | flowId (32 bits) |
116 */
117 this.id = FlowId.valueOf((((long) this.appId) << 48) | (((long) this.groupId.id()) << 32)
118 | (this.hash() & 0xffffffffL));
119
Sho SHIMIZU75a5bd92014-11-25 11:22:56 -0800120 }
121
alshabibdb774072015-04-20 13:13:51 -0700122 @Deprecated
alshabib28204e52014-11-12 18:29:45 -0800123 public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
124 TrafficTreatment treatment, int priority, ApplicationId appId,
Sho SHIMIZU75a5bd92014-11-25 11:22:56 -0800125 GroupId groupId, int timeout, boolean permanent) {
alshabiba7f7ca82014-09-22 11:41:23 -0700126
alshabib1c319ff2014-10-04 20:29:09 -0700127 if (priority < FlowRule.MIN_PRIORITY) {
alshabiba0e04982014-10-03 13:03:19 -0700128 throw new IllegalArgumentException("Priority cannot be less than " + MIN_PRIORITY);
129 }
alshabib1c319ff2014-10-04 20:29:09 -0700130
alshabib219ebaa2014-09-22 15:41:24 -0700131 this.deviceId = deviceId;
132 this.priority = priority;
133 this.selector = selector;
Ray Milkey1e207112014-11-11 10:38:00 -0800134 this.treatment = treatment;
alshabib92c65ad2014-10-08 21:56:05 -0700135 this.appId = appId.id();
alshabib28204e52014-11-12 18:29:45 -0800136 this.groupId = groupId;
alshabibba5ac482014-10-02 17:15:20 -0700137 this.timeout = timeout;
Jonathan Hartbc4a7932014-10-21 11:46:00 -0700138 this.permanent = permanent;
alshabib1c319ff2014-10-04 20:29:09 -0700139 this.created = System.currentTimeMillis();
alshabibdb774072015-04-20 13:13:51 -0700140 this.tableId = 0;
alshabibba5ac482014-10-02 17:15:20 -0700141
alshabib28204e52014-11-12 18:29:45 -0800142 /*
143 * id consists of the following.
144 * | appId (16 bits) | groupId (16 bits) | flowId (32 bits) |
145 */
Sho SHIMIZU75a5bd92014-11-25 11:22:56 -0800146 this.id = FlowId.valueOf((((long) this.appId) << 48) | (((long) this.groupId.id()) << 32)
147 | (this.hash() & 0xffffffffL));
alshabib219ebaa2014-09-22 15:41:24 -0700148 }
149
alshabib1c319ff2014-10-04 20:29:09 -0700150 public DefaultFlowRule(FlowRule rule) {
151 this.deviceId = rule.deviceId();
152 this.priority = rule.priority();
153 this.selector = rule.selector();
154 this.treatment = rule.treatment();
155 this.appId = rule.appId();
alshabib28204e52014-11-12 18:29:45 -0800156 this.groupId = rule.groupId();
alshabib1c319ff2014-10-04 20:29:09 -0700157 this.id = rule.id();
158 this.timeout = rule.timeout();
Jonathan Hartbc4a7932014-10-21 11:46:00 -0700159 this.permanent = rule.isPermanent();
alshabib219ebaa2014-09-22 15:41:24 -0700160 this.created = System.currentTimeMillis();
alshabibdb774072015-04-20 13:13:51 -0700161 this.tableId = rule.tableId();
162
163 }
164
165 private DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
166 TrafficTreatment treatment, Integer priority,
167 FlowId flowId, Boolean permanent, Integer timeout,
168 Integer tableId) {
169
170 this.deviceId = deviceId;
171 this.selector = selector;
172 this.treatment = treatment;
173 this.priority = priority;
174 this.appId = (short) (flowId.value() >>> 48);
175 this.id = flowId;
176 this.permanent = permanent;
177 this.timeout = timeout;
178 this.tableId = tableId;
179 this.created = System.currentTimeMillis();
180
181
182 //FIXME: fields below will be removed.
183 this.groupId = null;
alshabibdb774072015-04-20 13:13:51 -0700184
alshabib1c319ff2014-10-04 20:29:09 -0700185
alshabiba7f7ca82014-09-22 11:41:23 -0700186 }
187
Ayaka Koshibed4e53e12014-09-18 14:24:55 -0700188 @Override
189 public FlowId id() {
190 return id;
alshabib7b2748f2014-09-16 20:21:11 -0700191 }
192
193 @Override
alshabib92c65ad2014-10-08 21:56:05 -0700194 public short appId() {
alshabiba68eb962014-09-24 20:34:13 -0700195 return appId;
196 }
197
198 @Override
Sho SHIMIZU75a5bd92014-11-25 11:22:56 -0800199 public GroupId groupId() {
alshabib28204e52014-11-12 18:29:45 -0800200 return groupId;
201 }
202
203 @Override
alshabib7b2748f2014-09-16 20:21:11 -0700204 public int priority() {
Ayaka Koshibed4e53e12014-09-18 14:24:55 -0700205 return priority;
alshabib7b2748f2014-09-16 20:21:11 -0700206 }
207
208 @Override
209 public DeviceId deviceId() {
210 return deviceId;
211 }
212
213 @Override
214 public TrafficSelector selector() {
215 return selector;
216 }
217
218 @Override
219 public TrafficTreatment treatment() {
220 return treatment;
221 }
222
alshabiba7f7ca82014-09-22 11:41:23 -0700223 @Override
Ayaka Koshibed4e53e12014-09-18 14:24:55 -0700224 /*
225 * The priority and statistics can change on a given treatment and selector
226 *
227 * (non-Javadoc)
228 * @see java.lang.Object#equals(java.lang.Object)
229 */
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -0700230 public int hashCode() {
alshabib08d98982015-04-21 16:25:50 -0700231 return Objects.hash(deviceId, selector, priority, tableId);
alshabiba68eb962014-09-24 20:34:13 -0700232 }
233
234 public int hash() {
alshabib08d98982015-04-21 16:25:50 -0700235 return Objects.hash(deviceId, selector, treatment, tableId);
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -0700236 }
237
238 @Override
239 /*
240 * The priority and statistics can change on a given treatment and selector
241 *
242 * (non-Javadoc)
243 * @see java.lang.Object#equals(java.lang.Object)
244 */
245 public boolean equals(Object obj) {
alshabiba7f7ca82014-09-22 11:41:23 -0700246 if (this == obj) {
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700247 return true;
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -0700248 }
alshabib54ce5892014-09-23 17:50:51 -0700249 if (obj instanceof DefaultFlowRule) {
alshabib219ebaa2014-09-22 15:41:24 -0700250 DefaultFlowRule that = (DefaultFlowRule) obj;
251 return Objects.equals(deviceId, that.deviceId) &&
alshabibba5ac482014-10-02 17:15:20 -0700252 Objects.equals(priority, that.priority) &&
Saurav Dascbe6de32015-03-01 18:30:46 -0800253 Objects.equals(selector, that.selector) &&
alshabib08d98982015-04-21 16:25:50 -0700254 Objects.equals(tableId, that.tableId);
alshabibba5ac482014-10-02 17:15:20 -0700255
alshabiba7f7ca82014-09-22 11:41:23 -0700256 }
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700257 return false;
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -0700258 }
259
Ayaka Koshibed4e53e12014-09-18 14:24:55 -0700260 @Override
261 public String toString() {
262 return toStringHelper(this)
alshabib8ca53902014-10-07 13:11:17 -0700263 .add("id", Long.toHexString(id.value()))
Ayaka Koshibed4e53e12014-09-18 14:24:55 -0700264 .add("deviceId", deviceId)
265 .add("priority", priority)
alshabibba5ac482014-10-02 17:15:20 -0700266 .add("selector", selector.criteria())
Jonathan Hart8ef6d3b2015-03-08 21:21:27 -0700267 .add("treatment", treatment == null ? "N/A" : treatment.allInstructions())
alshabib08d98982015-04-21 16:25:50 -0700268 .add("tableId", tableId)
Ayaka Koshibed4e53e12014-09-18 14:24:55 -0700269 .add("created", created)
270 .toString();
271 }
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -0700272
alshabib6eb438a2014-10-01 16:39:37 -0700273 @Override
alshabibba5ac482014-10-02 17:15:20 -0700274 public int timeout() {
alshabib58747a62014-10-07 11:05:30 -0700275 return timeout;
alshabib6eb438a2014-10-01 16:39:37 -0700276 }
277
Jonathan Hartbc4a7932014-10-21 11:46:00 -0700278 @Override
279 public boolean isPermanent() {
280 return permanent;
281 }
282
sangho11c30ac2015-01-22 14:30:55 -0800283 @Override
alshabibdb774072015-04-20 13:13:51 -0700284 public int tableId() {
285 return tableId;
286 }
287
288 public static Builder builder() {
289 return new Builder();
290 }
291
alshabibd17abc22015-04-21 18:26:35 -0700292 public static final class Builder implements FlowRule.Builder {
alshabibdb774072015-04-20 13:13:51 -0700293
294 private FlowId flowId;
295 private Integer priority;
296 private DeviceId deviceId;
297 private Integer tableId = 0;
298 private TrafficSelector selector;
299 private TrafficTreatment treatment;
300 private Integer timeout;
301 private Boolean permanent;
302
303 @Override
304 public FlowRule.Builder withCookie(long cookie) {
305 this.flowId = FlowId.valueOf(cookie);
306 return this;
307 }
308
309 @Override
310 public FlowRule.Builder fromApp(ApplicationId appId) {
311 this.flowId = computeFlowId(appId);
312 return this;
313 }
314
315 @Override
316 public FlowRule.Builder withPriority(int priority) {
317 this.priority = priority;
318 return this;
319 }
320
321 @Override
322 public FlowRule.Builder forDevice(DeviceId deviceId) {
323 this.deviceId = deviceId;
324 return this;
325 }
326
327 @Override
328 public FlowRule.Builder forTable(int tableId) {
329 this.tableId = tableId;
330 return this;
331 }
332
333 @Override
334 public FlowRule.Builder withSelector(TrafficSelector selector) {
335 this.selector = selector;
336 return this;
337 }
338
339 @Override
340 public FlowRule.Builder withTreatment(TrafficTreatment treatment) {
341 this.treatment = treatment;
342 return this;
343 }
344
345 @Override
346 public FlowRule.Builder makePermanent() {
347 this.timeout = 0;
348 this.permanent = true;
349 return this;
350 }
351
352 @Override
353 public FlowRule.Builder makeTemporary(int timeout) {
354 this.permanent = false;
355 this.timeout = timeout;
356 return this;
357 }
358
359 @Override
360 public FlowRule build() {
361 checkNotNull(flowId != null, "Either an application" +
362 " id or a cookie must be supplied");
363 checkNotNull(selector != null, "Traffic selector cannot be null");
364 checkNotNull(timeout != null || permanent != null, "Must either have " +
365 "a timeout or be permanent");
366 checkNotNull(deviceId != null, "Must refer to a device");
367 checkNotNull(priority != null, "Priority cannot be null");
368 checkArgument(priority < MIN_PRIORITY, "Priority cannot be less than " +
369 MIN_PRIORITY);
370
371 return new DefaultFlowRule(deviceId, selector, treatment, priority,
372 flowId, permanent, timeout, tableId);
373 }
374
375 private FlowId computeFlowId(ApplicationId appId) {
376 return FlowId.valueOf((((long) appId.id()) << 48)
377 | (hash() & 0xffffffffL));
378 }
379
380 private int hash() {
381 return Objects.hash(deviceId, selector, treatment, tableId);
382 }
383
384 }
385
alshabib7b2748f2014-09-16 20:21:11 -0700386}