blob: 63baa68847bd56da79fcd5784cf128232cc87278 [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
sangho11c30ac2015-01-22 14:30:55 -080045 private final Type type;
alshabibdb774072015-04-20 13:13:51 -070046 private final Integer tableId;
sangho11c30ac2015-01-22 14:30:55 -080047
alshabib1c319ff2014-10-04 20:29:09 -070048
alshabibdb774072015-04-20 13:13:51 -070049 @Deprecated
alshabib97044902014-09-18 14:52:16 -070050 public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
alshabib1c319ff2014-10-04 20:29:09 -070051 TrafficTreatment treatment, int priority, long flowId,
Jonathan Hartbc4a7932014-10-21 11:46:00 -070052 int timeout, boolean permanent) {
alshabib6b5cfec2014-09-18 17:42:18 -070053 this.deviceId = deviceId;
54 this.priority = priority;
55 this.selector = selector;
56 this.treatment = treatment;
alshabib1c319ff2014-10-04 20:29:09 -070057 this.timeout = timeout;
Jonathan Hartbc4a7932014-10-21 11:46:00 -070058 this.permanent = permanent;
alshabib1c319ff2014-10-04 20:29:09 -070059 this.created = System.currentTimeMillis();
60
alshabib92c65ad2014-10-08 21:56:05 -070061 this.appId = (short) (flowId >>> 48);
Sho SHIMIZU75a5bd92014-11-25 11:22:56 -080062 this.groupId = new DefaultGroupId((short) ((flowId >>> 32) & 0xFFFF));
alshabib6b5cfec2014-09-18 17:42:18 -070063 this.id = FlowId.valueOf(flowId);
sangho11c30ac2015-01-22 14:30:55 -080064 this.type = Type.DEFAULT;
alshabibdb774072015-04-20 13:13:51 -070065 this.tableId = 0;
alshabib97044902014-09-18 14:52:16 -070066 }
67
alshabibdb774072015-04-20 13:13:51 -070068 @Deprecated
alshabiba7f7ca82014-09-22 11:41:23 -070069 public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
Saurav Dasfa2fa932015-03-03 11:29:48 -080070 TrafficTreatment treatment, int priority, long flowId,
71 int timeout, boolean permanent, Type tableType) {
72 this.deviceId = deviceId;
73 this.priority = priority;
74 this.selector = selector;
75 this.treatment = treatment;
76 this.timeout = timeout;
77 this.permanent = permanent;
78 this.created = System.currentTimeMillis();
79
80 this.appId = (short) (flowId >>> 48);
81 this.groupId = new DefaultGroupId((short) ((flowId >>> 32) & 0xFFFF));
82 this.id = FlowId.valueOf(flowId);
83 this.type = tableType;
alshabibdb774072015-04-20 13:13:51 -070084 this.tableId = 0;
85
Saurav Dasfa2fa932015-03-03 11:29:48 -080086 }
87
alshabibdb774072015-04-20 13:13:51 -070088 @Deprecated
Saurav Dasfa2fa932015-03-03 11:29:48 -080089 public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
alshabib28204e52014-11-12 18:29:45 -080090 TrafficTreatment treatment, int priority, ApplicationId appId,
91 int timeout, boolean permanent) {
sangho11c30ac2015-01-22 14:30:55 -080092 this(deviceId, selector, treatment, priority, appId, new DefaultGroupId(0),
93 timeout, permanent);
94 }
95
alshabibdb774072015-04-20 13:13:51 -070096 @Deprecated
sangho11c30ac2015-01-22 14:30:55 -080097 public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
98 TrafficTreatment treatment, int priority, ApplicationId appId,
99 int timeout, boolean permanent, Type type) {
100
101 if (priority < FlowRule.MIN_PRIORITY) {
102 throw new IllegalArgumentException("Priority cannot be less than " + MIN_PRIORITY);
103 }
104
105 this.deviceId = deviceId;
106 this.priority = priority;
107 this.selector = selector;
108 this.treatment = treatment;
109 this.appId = appId.id();
110 this.groupId = new DefaultGroupId(0);
111 this.timeout = timeout;
112 this.permanent = permanent;
113 this.created = System.currentTimeMillis();
114 this.type = type;
alshabibdb774072015-04-20 13:13:51 -0700115 this.tableId = 0;
sangho11c30ac2015-01-22 14:30:55 -0800116
117 /*
118 * id consists of the following.
119 * | appId (16 bits) | groupId (16 bits) | flowId (32 bits) |
120 */
121 this.id = FlowId.valueOf((((long) this.appId) << 48) | (((long) this.groupId.id()) << 32)
122 | (this.hash() & 0xffffffffL));
123
Sho SHIMIZU75a5bd92014-11-25 11:22:56 -0800124 }
125
alshabibdb774072015-04-20 13:13:51 -0700126 @Deprecated
alshabib28204e52014-11-12 18:29:45 -0800127 public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
128 TrafficTreatment treatment, int priority, ApplicationId appId,
Sho SHIMIZU75a5bd92014-11-25 11:22:56 -0800129 GroupId groupId, int timeout, boolean permanent) {
alshabiba7f7ca82014-09-22 11:41:23 -0700130
alshabib1c319ff2014-10-04 20:29:09 -0700131 if (priority < FlowRule.MIN_PRIORITY) {
alshabiba0e04982014-10-03 13:03:19 -0700132 throw new IllegalArgumentException("Priority cannot be less than " + MIN_PRIORITY);
133 }
alshabib1c319ff2014-10-04 20:29:09 -0700134
alshabib219ebaa2014-09-22 15:41:24 -0700135 this.deviceId = deviceId;
136 this.priority = priority;
137 this.selector = selector;
Ray Milkey1e207112014-11-11 10:38:00 -0800138 this.treatment = treatment;
alshabib92c65ad2014-10-08 21:56:05 -0700139 this.appId = appId.id();
alshabib28204e52014-11-12 18:29:45 -0800140 this.groupId = groupId;
alshabibba5ac482014-10-02 17:15:20 -0700141 this.timeout = timeout;
Jonathan Hartbc4a7932014-10-21 11:46:00 -0700142 this.permanent = permanent;
alshabib1c319ff2014-10-04 20:29:09 -0700143 this.created = System.currentTimeMillis();
sangho11c30ac2015-01-22 14:30:55 -0800144 this.type = Type.DEFAULT;
alshabibdb774072015-04-20 13:13:51 -0700145 this.tableId = 0;
alshabibba5ac482014-10-02 17:15:20 -0700146
alshabib28204e52014-11-12 18:29:45 -0800147 /*
148 * id consists of the following.
149 * | appId (16 bits) | groupId (16 bits) | flowId (32 bits) |
150 */
Sho SHIMIZU75a5bd92014-11-25 11:22:56 -0800151 this.id = FlowId.valueOf((((long) this.appId) << 48) | (((long) this.groupId.id()) << 32)
152 | (this.hash() & 0xffffffffL));
alshabib219ebaa2014-09-22 15:41:24 -0700153 }
154
alshabib1c319ff2014-10-04 20:29:09 -0700155 public DefaultFlowRule(FlowRule rule) {
156 this.deviceId = rule.deviceId();
157 this.priority = rule.priority();
158 this.selector = rule.selector();
159 this.treatment = rule.treatment();
160 this.appId = rule.appId();
alshabib28204e52014-11-12 18:29:45 -0800161 this.groupId = rule.groupId();
alshabib1c319ff2014-10-04 20:29:09 -0700162 this.id = rule.id();
163 this.timeout = rule.timeout();
Jonathan Hartbc4a7932014-10-21 11:46:00 -0700164 this.permanent = rule.isPermanent();
alshabib219ebaa2014-09-22 15:41:24 -0700165 this.created = System.currentTimeMillis();
sangho11c30ac2015-01-22 14:30:55 -0800166 this.type = rule.type();
alshabibdb774072015-04-20 13:13:51 -0700167 this.tableId = rule.tableId();
168
169 }
170
171 private DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
172 TrafficTreatment treatment, Integer priority,
173 FlowId flowId, Boolean permanent, Integer timeout,
174 Integer tableId) {
175
176 this.deviceId = deviceId;
177 this.selector = selector;
178 this.treatment = treatment;
179 this.priority = priority;
180 this.appId = (short) (flowId.value() >>> 48);
181 this.id = flowId;
182 this.permanent = permanent;
183 this.timeout = timeout;
184 this.tableId = tableId;
185 this.created = System.currentTimeMillis();
186
187
188 //FIXME: fields below will be removed.
189 this.groupId = null;
190 this.type = null;
191
alshabib1c319ff2014-10-04 20:29:09 -0700192
alshabiba7f7ca82014-09-22 11:41:23 -0700193 }
194
Ayaka Koshibed4e53e12014-09-18 14:24:55 -0700195 @Override
196 public FlowId id() {
197 return id;
alshabib7b2748f2014-09-16 20:21:11 -0700198 }
199
200 @Override
alshabib92c65ad2014-10-08 21:56:05 -0700201 public short appId() {
alshabiba68eb962014-09-24 20:34:13 -0700202 return appId;
203 }
204
205 @Override
Sho SHIMIZU75a5bd92014-11-25 11:22:56 -0800206 public GroupId groupId() {
alshabib28204e52014-11-12 18:29:45 -0800207 return groupId;
208 }
209
210 @Override
alshabib7b2748f2014-09-16 20:21:11 -0700211 public int priority() {
Ayaka Koshibed4e53e12014-09-18 14:24:55 -0700212 return priority;
alshabib7b2748f2014-09-16 20:21:11 -0700213 }
214
215 @Override
216 public DeviceId deviceId() {
217 return deviceId;
218 }
219
220 @Override
221 public TrafficSelector selector() {
222 return selector;
223 }
224
225 @Override
226 public TrafficTreatment treatment() {
227 return treatment;
228 }
229
alshabiba7f7ca82014-09-22 11:41:23 -0700230 @Override
Ayaka Koshibed4e53e12014-09-18 14:24:55 -0700231 /*
232 * The priority and statistics can change on a given treatment and selector
233 *
234 * (non-Javadoc)
235 * @see java.lang.Object#equals(java.lang.Object)
236 */
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -0700237 public int hashCode() {
alshabibdb774072015-04-20 13:13:51 -0700238 return Objects.hash(deviceId, selector, priority, type, tableId);
alshabiba68eb962014-09-24 20:34:13 -0700239 }
240
241 public int hash() {
Saurav Dascbe6de32015-03-01 18:30:46 -0800242 return Objects.hash(deviceId, selector, treatment, type);
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -0700243 }
244
245 @Override
246 /*
247 * The priority and statistics can change on a given treatment and selector
248 *
249 * (non-Javadoc)
250 * @see java.lang.Object#equals(java.lang.Object)
251 */
252 public boolean equals(Object obj) {
alshabiba7f7ca82014-09-22 11:41:23 -0700253 if (this == obj) {
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700254 return true;
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -0700255 }
alshabib54ce5892014-09-23 17:50:51 -0700256 if (obj instanceof DefaultFlowRule) {
alshabib219ebaa2014-09-22 15:41:24 -0700257 DefaultFlowRule that = (DefaultFlowRule) obj;
258 return Objects.equals(deviceId, that.deviceId) &&
alshabibba5ac482014-10-02 17:15:20 -0700259 Objects.equals(priority, that.priority) &&
Saurav Dascbe6de32015-03-01 18:30:46 -0800260 Objects.equals(selector, that.selector) &&
alshabibdb774072015-04-20 13:13:51 -0700261 Objects.equals(tableId, that.tableId) &&
Saurav Dascbe6de32015-03-01 18:30:46 -0800262 Objects.equals(type, that.type);
alshabibba5ac482014-10-02 17:15:20 -0700263
alshabiba7f7ca82014-09-22 11:41:23 -0700264 }
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700265 return false;
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -0700266 }
267
Ayaka Koshibed4e53e12014-09-18 14:24:55 -0700268 @Override
269 public String toString() {
270 return toStringHelper(this)
alshabib8ca53902014-10-07 13:11:17 -0700271 .add("id", Long.toHexString(id.value()))
Ayaka Koshibed4e53e12014-09-18 14:24:55 -0700272 .add("deviceId", deviceId)
273 .add("priority", priority)
alshabibba5ac482014-10-02 17:15:20 -0700274 .add("selector", selector.criteria())
Jonathan Hart8ef6d3b2015-03-08 21:21:27 -0700275 .add("treatment", treatment == null ? "N/A" : treatment.allInstructions())
Saurav Dascbe6de32015-03-01 18:30:46 -0800276 .add("table type", type)
Ayaka Koshibed4e53e12014-09-18 14:24:55 -0700277 .add("created", created)
278 .toString();
279 }
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -0700280
alshabib6eb438a2014-10-01 16:39:37 -0700281 @Override
alshabibba5ac482014-10-02 17:15:20 -0700282 public int timeout() {
alshabib58747a62014-10-07 11:05:30 -0700283 return timeout;
alshabib6eb438a2014-10-01 16:39:37 -0700284 }
285
Jonathan Hartbc4a7932014-10-21 11:46:00 -0700286 @Override
287 public boolean isPermanent() {
288 return permanent;
289 }
290
sangho11c30ac2015-01-22 14:30:55 -0800291 @Override
292 public Type type() {
293 return type;
294 }
295
alshabibdb774072015-04-20 13:13:51 -0700296 @Override
297 public int tableId() {
298 return tableId;
299 }
300
301 public static Builder builder() {
302 return new Builder();
303 }
304
305 private static final class Builder implements FlowRule.Builder {
306
307 private FlowId flowId;
308 private Integer priority;
309 private DeviceId deviceId;
310 private Integer tableId = 0;
311 private TrafficSelector selector;
312 private TrafficTreatment treatment;
313 private Integer timeout;
314 private Boolean permanent;
315
316 @Override
317 public FlowRule.Builder withCookie(long cookie) {
318 this.flowId = FlowId.valueOf(cookie);
319 return this;
320 }
321
322 @Override
323 public FlowRule.Builder fromApp(ApplicationId appId) {
324 this.flowId = computeFlowId(appId);
325 return this;
326 }
327
328 @Override
329 public FlowRule.Builder withPriority(int priority) {
330 this.priority = priority;
331 return this;
332 }
333
334 @Override
335 public FlowRule.Builder forDevice(DeviceId deviceId) {
336 this.deviceId = deviceId;
337 return this;
338 }
339
340 @Override
341 public FlowRule.Builder forTable(int tableId) {
342 this.tableId = tableId;
343 return this;
344 }
345
346 @Override
347 public FlowRule.Builder withSelector(TrafficSelector selector) {
348 this.selector = selector;
349 return this;
350 }
351
352 @Override
353 public FlowRule.Builder withTreatment(TrafficTreatment treatment) {
354 this.treatment = treatment;
355 return this;
356 }
357
358 @Override
359 public FlowRule.Builder makePermanent() {
360 this.timeout = 0;
361 this.permanent = true;
362 return this;
363 }
364
365 @Override
366 public FlowRule.Builder makeTemporary(int timeout) {
367 this.permanent = false;
368 this.timeout = timeout;
369 return this;
370 }
371
372 @Override
373 public FlowRule build() {
374 checkNotNull(flowId != null, "Either an application" +
375 " id or a cookie must be supplied");
376 checkNotNull(selector != null, "Traffic selector cannot be null");
377 checkNotNull(timeout != null || permanent != null, "Must either have " +
378 "a timeout or be permanent");
379 checkNotNull(deviceId != null, "Must refer to a device");
380 checkNotNull(priority != null, "Priority cannot be null");
381 checkArgument(priority < MIN_PRIORITY, "Priority cannot be less than " +
382 MIN_PRIORITY);
383
384 return new DefaultFlowRule(deviceId, selector, treatment, priority,
385 flowId, permanent, timeout, tableId);
386 }
387
388 private FlowId computeFlowId(ApplicationId appId) {
389 return FlowId.valueOf((((long) appId.id()) << 48)
390 | (hash() & 0xffffffffL));
391 }
392
393 private int hash() {
394 return Objects.hash(deviceId, selector, treatment, tableId);
395 }
396
397 }
398
alshabib7b2748f2014-09-16 20:21:11 -0700399}