blob: 44a4d364954d1bbe139c4df6efe313ae02fd0b80 [file] [log] [blame]
Thomas Vachuska83e090e2014-10-22 14:25:35 -07001/*
jcc3d4e14a2015-04-21 11:32:05 +08002 * 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;
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 Hart607b1ff2015-05-05 10:55:51 -070023import java.util.Objects;
24
25import static com.google.common.base.MoreObjects.toStringHelper;
26import static com.google.common.base.Preconditions.checkArgument;
27import static com.google.common.base.Preconditions.checkNotNull;
28
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;
jcc3d4e14a2015-04-21 11:32:05 +080046 private final FlowRuleExtPayLoad payLoad;
alshabib1c319ff2014-10-04 20:29:09 -070047
alshabib1c319ff2014-10-04 20:29:09 -070048 public DefaultFlowRule(FlowRule rule) {
49 this.deviceId = rule.deviceId();
50 this.priority = rule.priority();
51 this.selector = rule.selector();
52 this.treatment = rule.treatment();
53 this.appId = rule.appId();
alshabib28204e52014-11-12 18:29:45 -080054 this.groupId = rule.groupId();
alshabib1c319ff2014-10-04 20:29:09 -070055 this.id = rule.id();
56 this.timeout = rule.timeout();
Jonathan Hartbc4a7932014-10-21 11:46:00 -070057 this.permanent = rule.isPermanent();
alshabib219ebaa2014-09-22 15:41:24 -070058 this.created = System.currentTimeMillis();
alshabibdb774072015-04-20 13:13:51 -070059 this.tableId = rule.tableId();
jcc3d4e14a2015-04-21 11:32:05 +080060 this.payLoad = rule.payLoad();
alshabibdb774072015-04-20 13:13:51 -070061 }
62
63 private DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
64 TrafficTreatment treatment, Integer priority,
65 FlowId flowId, Boolean permanent, Integer timeout,
66 Integer tableId) {
67
68 this.deviceId = deviceId;
69 this.selector = selector;
70 this.treatment = treatment;
71 this.priority = priority;
72 this.appId = (short) (flowId.value() >>> 48);
73 this.id = flowId;
74 this.permanent = permanent;
75 this.timeout = timeout;
76 this.tableId = tableId;
77 this.created = System.currentTimeMillis();
78
79
80 //FIXME: fields below will be removed.
Jonathan Hart607b1ff2015-05-05 10:55:51 -070081 this.groupId = new DefaultGroupId(0);
jcc3d4e14a2015-04-21 11:32:05 +080082 this.payLoad = null;
83 }
alshabibdb774072015-04-20 13:13:51 -070084
jcc3d4e14a2015-04-21 11:32:05 +080085 /**
86 * Support for the third party flow rule. Creates a flow rule of flow table.
87 *
88 * @param deviceId the identity of the device where this rule applies
89 * @param selector the traffic selector that identifies what traffic this
90 * rule
91 * @param treatment the traffic treatment that applies to selected traffic
92 * @param priority the flow rule priority given in natural order
93 * @param appId the application id of this flow
94 * @param timeout the timeout for this flow requested by an application
95 * @param permanent whether the flow is permanent i.e. does not time out
96 * @param payLoad 3rd-party origin private flow
97 */
98 public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
99 TrafficTreatment treatment, int priority,
100 ApplicationId appId, int timeout, boolean permanent,
101 FlowRuleExtPayLoad payLoad) {
alshabib1c319ff2014-10-04 20:29:09 -0700102
jcc3d4e14a2015-04-21 11:32:05 +0800103 if (priority < FlowRule.MIN_PRIORITY) {
104 throw new IllegalArgumentException("Priority cannot be less than "
105 + MIN_PRIORITY);
106 }
107
108 this.deviceId = deviceId;
109 this.priority = priority;
110 this.selector = selector;
111 this.treatment = treatment;
112 this.appId = appId.id();
113 this.groupId = new DefaultGroupId(0);
114 this.timeout = timeout;
115 this.permanent = permanent;
116 this.tableId = 0;
117 this.created = System.currentTimeMillis();
118 this.payLoad = payLoad;
119
120 /*
121 * id consists of the following. | appId (16 bits) | groupId (16 bits) |
122 * flowId (32 bits) |
123 */
124 this.id = FlowId.valueOf((((long) this.appId) << 48)
125 | (((long) this.groupId.id()) << 32)
126 | (this.hash() & 0xffffffffL));
127 }
128
129 /**
130 * Support for the third party flow rule. Creates a flow rule of group
131 * table.
132 *
133 * @param deviceId the identity of the device where this rule applies
134 * @param selector the traffic selector that identifies what traffic this
135 * rule
136 * @param treatment the traffic treatment that applies to selected traffic
137 * @param priority the flow rule priority given in natural order
138 * @param appId the application id of this flow
139 * @param groupId the group id of this flow
140 * @param timeout the timeout for this flow requested by an application
141 * @param permanent whether the flow is permanent i.e. does not time out
142 * @param payLoad 3rd-party origin private flow
143 *
144 */
145 public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
146 TrafficTreatment treatment, int priority,
147 ApplicationId appId, GroupId groupId, int timeout,
148 boolean permanent, FlowRuleExtPayLoad payLoad) {
149
150 if (priority < FlowRule.MIN_PRIORITY) {
151 throw new IllegalArgumentException("Priority cannot be less than "
152 + MIN_PRIORITY);
153 }
154
155 this.deviceId = deviceId;
156 this.priority = priority;
157 this.selector = selector;
158 this.treatment = treatment;
159 this.appId = appId.id();
160 this.groupId = groupId;
161 this.timeout = timeout;
162 this.permanent = permanent;
163 this.created = System.currentTimeMillis();
164 this.tableId = 0;
165 this.payLoad = payLoad;
166
167 /*
168 * id consists of the following. | appId (16 bits) | groupId (16 bits) |
169 * flowId (32 bits) |
170 */
171 this.id = FlowId.valueOf((((long) this.appId) << 48)
172 | (((long) this.groupId.id()) << 32)
173 | (this.hash() & 0xffffffffL));
alshabiba7f7ca82014-09-22 11:41:23 -0700174 }
175
Ayaka Koshibed4e53e12014-09-18 14:24:55 -0700176 @Override
177 public FlowId id() {
178 return id;
alshabib7b2748f2014-09-16 20:21:11 -0700179 }
180
181 @Override
alshabib92c65ad2014-10-08 21:56:05 -0700182 public short appId() {
alshabiba68eb962014-09-24 20:34:13 -0700183 return appId;
184 }
185
186 @Override
Sho SHIMIZU75a5bd92014-11-25 11:22:56 -0800187 public GroupId groupId() {
alshabib28204e52014-11-12 18:29:45 -0800188 return groupId;
189 }
190
191 @Override
alshabib7b2748f2014-09-16 20:21:11 -0700192 public int priority() {
Ayaka Koshibed4e53e12014-09-18 14:24:55 -0700193 return priority;
alshabib7b2748f2014-09-16 20:21:11 -0700194 }
195
196 @Override
197 public DeviceId deviceId() {
198 return deviceId;
199 }
200
201 @Override
202 public TrafficSelector selector() {
203 return selector;
204 }
205
206 @Override
207 public TrafficTreatment treatment() {
208 return treatment;
209 }
210
alshabiba7f7ca82014-09-22 11:41:23 -0700211 @Override
Ayaka Koshibed4e53e12014-09-18 14:24:55 -0700212 /*
213 * The priority and statistics can change on a given treatment and selector
214 *
215 * (non-Javadoc)
jcc3d4e14a2015-04-21 11:32:05 +0800216 *
Ayaka Koshibed4e53e12014-09-18 14:24:55 -0700217 * @see java.lang.Object#equals(java.lang.Object)
218 */
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -0700219 public int hashCode() {
Thomas Vachuska711db552015-06-02 16:35:26 -0700220 return Objects.hash(deviceId, selector, tableId, payLoad);
alshabiba68eb962014-09-24 20:34:13 -0700221 }
222
Thomas Vachuska711db552015-06-02 16:35:26 -0700223 //FIXME do we need this method in addition to hashCode()?
224 private int hash() {
225 return Objects.hash(deviceId, selector, tableId, payLoad);
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -0700226 }
227
228 @Override
229 /*
230 * The priority and statistics can change on a given treatment and selector
231 *
232 * (non-Javadoc)
jcc3d4e14a2015-04-21 11:32:05 +0800233 *
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -0700234 * @see java.lang.Object#equals(java.lang.Object)
235 */
236 public boolean equals(Object obj) {
alshabiba7f7ca82014-09-22 11:41:23 -0700237 if (this == obj) {
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700238 return true;
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -0700239 }
alshabib54ce5892014-09-23 17:50:51 -0700240 if (obj instanceof DefaultFlowRule) {
alshabib219ebaa2014-09-22 15:41:24 -0700241 DefaultFlowRule that = (DefaultFlowRule) obj;
242 return Objects.equals(deviceId, that.deviceId) &&
alshabibba5ac482014-10-02 17:15:20 -0700243 Objects.equals(priority, that.priority) &&
Saurav Dascbe6de32015-03-01 18:30:46 -0800244 Objects.equals(selector, that.selector) &&
jcc3d4e14a2015-04-21 11:32:05 +0800245 Objects.equals(tableId, that.tableId)
246 && Objects.equals(payLoad, that.payLoad);
alshabiba7f7ca82014-09-22 11:41:23 -0700247 }
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700248 return false;
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -0700249 }
250
Ayaka Koshibed4e53e12014-09-18 14:24:55 -0700251 @Override
Jonathan Hartf44e42c2015-08-04 09:58:46 -0700252 public boolean exactMatch(FlowRule rule) {
253 return this.equals(rule) &&
254 Objects.equals(this.id, rule.id()) &&
255 Objects.equals(this.treatment, rule.treatment());
256 }
257
258 @Override
Ayaka Koshibed4e53e12014-09-18 14:24:55 -0700259 public String toString() {
260 return toStringHelper(this)
alshabib8ca53902014-10-07 13:11:17 -0700261 .add("id", Long.toHexString(id.value()))
Ayaka Koshibed4e53e12014-09-18 14:24:55 -0700262 .add("deviceId", deviceId)
263 .add("priority", priority)
alshabibba5ac482014-10-02 17:15:20 -0700264 .add("selector", selector.criteria())
Jonathan Hart8ef6d3b2015-03-08 21:21:27 -0700265 .add("treatment", treatment == null ? "N/A" : treatment.allInstructions())
alshabib08d98982015-04-21 16:25:50 -0700266 .add("tableId", tableId)
Ayaka Koshibed4e53e12014-09-18 14:24:55 -0700267 .add("created", created)
Ray Milkeyd13a37b2015-06-12 11:55:17 -0700268 .add("payLoad", payLoad)
Ayaka Koshibed4e53e12014-09-18 14:24:55 -0700269 .toString();
270 }
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -0700271
alshabib6eb438a2014-10-01 16:39:37 -0700272 @Override
alshabibba5ac482014-10-02 17:15:20 -0700273 public int timeout() {
alshabib58747a62014-10-07 11:05:30 -0700274 return timeout;
alshabib6eb438a2014-10-01 16:39:37 -0700275 }
276
Jonathan Hartbc4a7932014-10-21 11:46:00 -0700277 @Override
278 public boolean isPermanent() {
279 return permanent;
280 }
281
sangho11c30ac2015-01-22 14:30:55 -0800282 @Override
alshabibdb774072015-04-20 13:13:51 -0700283 public int tableId() {
284 return tableId;
285 }
286
287 public static Builder builder() {
288 return new Builder();
289 }
290
alshabibd17abc22015-04-21 18:26:35 -0700291 public static final class Builder implements FlowRule.Builder {
alshabibdb774072015-04-20 13:13:51 -0700292
293 private FlowId flowId;
294 private Integer priority;
295 private DeviceId deviceId;
296 private Integer tableId = 0;
297 private TrafficSelector selector;
298 private TrafficTreatment treatment;
299 private Integer timeout;
300 private Boolean permanent;
301
302 @Override
303 public FlowRule.Builder withCookie(long cookie) {
304 this.flowId = FlowId.valueOf(cookie);
305 return this;
306 }
307
308 @Override
309 public FlowRule.Builder fromApp(ApplicationId appId) {
310 this.flowId = computeFlowId(appId);
311 return this;
312 }
313
314 @Override
315 public FlowRule.Builder withPriority(int priority) {
316 this.priority = priority;
317 return this;
318 }
319
320 @Override
321 public FlowRule.Builder forDevice(DeviceId deviceId) {
322 this.deviceId = deviceId;
323 return this;
324 }
325
326 @Override
327 public FlowRule.Builder forTable(int tableId) {
328 this.tableId = tableId;
329 return this;
330 }
331
332 @Override
333 public FlowRule.Builder withSelector(TrafficSelector selector) {
334 this.selector = selector;
335 return this;
336 }
337
338 @Override
339 public FlowRule.Builder withTreatment(TrafficTreatment treatment) {
340 this.treatment = treatment;
341 return this;
342 }
343
344 @Override
345 public FlowRule.Builder makePermanent() {
346 this.timeout = 0;
347 this.permanent = true;
348 return this;
349 }
350
351 @Override
352 public FlowRule.Builder makeTemporary(int timeout) {
353 this.permanent = false;
354 this.timeout = timeout;
355 return this;
356 }
357
358 @Override
359 public FlowRule build() {
360 checkNotNull(flowId != null, "Either an application" +
361 " id or a cookie must be supplied");
362 checkNotNull(selector != null, "Traffic selector cannot be null");
363 checkNotNull(timeout != null || permanent != null, "Must either have " +
364 "a timeout or be permanent");
365 checkNotNull(deviceId != null, "Must refer to a device");
366 checkNotNull(priority != null, "Priority cannot be null");
Saurav Das3ea46622015-04-22 14:01:34 -0700367 checkArgument(priority >= MIN_PRIORITY, "Priority cannot be less than " +
alshabibdb774072015-04-20 13:13:51 -0700368 MIN_PRIORITY);
369
370 return new DefaultFlowRule(deviceId, selector, treatment, priority,
371 flowId, permanent, timeout, tableId);
372 }
373
374 private FlowId computeFlowId(ApplicationId appId) {
375 return FlowId.valueOf((((long) appId.id()) << 48)
376 | (hash() & 0xffffffffL));
377 }
378
379 private int hash() {
Jonathan Hartf44e42c2015-08-04 09:58:46 -0700380 return Objects.hash(deviceId, priority, selector, tableId);
alshabibdb774072015-04-20 13:13:51 -0700381 }
382
383 }
384
jcc3d4e14a2015-04-21 11:32:05 +0800385 @Override
386 public FlowRuleExtPayLoad payLoad() {
387 return payLoad;
388 }
389
alshabib7b2748f2014-09-16 20:21:11 -0700390}