blob: a4176b10133d66793a0e833235835fc1fadfcd45 [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.instructions;
alshabib55a55d92014-09-16 11:59:31 -070017
alshabib7b808c52015-06-26 14:22:24 -070018import org.onlab.packet.EthType;
Ayaka Koshibea9c199f2014-09-16 16:21:40 -070019import org.onlab.packet.MacAddress;
Michele Santuari4b6019e2014-12-19 11:31:45 +010020import org.onlab.packet.MplsLabel;
Ayaka Koshibea9c199f2014-09-16 16:21:40 -070021import org.onlab.packet.VlanId;
alshabib55a55d92014-09-16 11:59:31 -070022
Jonathan Hart54b406b2015-03-06 16:24:14 -080023import java.util.Objects;
24
25import static com.google.common.base.MoreObjects.toStringHelper;
26
alshabib55a55d92014-09-16 11:59:31 -070027/**
28 * Abstraction of a single traffic treatment step.
alshabib55a55d92014-09-16 11:59:31 -070029 */
30public abstract class L2ModificationInstruction implements Instruction {
31
32 /**
33 * Represents the type of traffic treatment.
34 */
alshabib35edb1a2014-09-16 17:44:44 -070035 public enum L2SubType {
alshabib55a55d92014-09-16 11:59:31 -070036 /**
37 * Ether src modification.
38 */
alshabib99b8fdc2014-09-25 14:30:22 -070039 ETH_SRC,
alshabib55a55d92014-09-16 11:59:31 -070040
41 /**
42 * Ether dst modification.
43 */
alshabib99b8fdc2014-09-25 14:30:22 -070044 ETH_DST,
alshabib55a55d92014-09-16 11:59:31 -070045
46 /**
alshabib55a55d92014-09-16 11:59:31 -070047 * VLAN id modification.
48 */
49 VLAN_ID,
50
51 /**
52 * VLAN priority modification.
53 */
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -080054 VLAN_PCP,
55
56 /**
57 * MPLS Label modification.
58 */
59 MPLS_LABEL,
60
61 /**
62 * MPLS Push modification.
63 */
64 MPLS_PUSH,
65
66 /**
67 * MPLS Pop modification.
68 */
sangho3f97a17d2015-01-29 22:56:29 -080069 MPLS_POP,
70
71 /**
72 * MPLS TTL modification.
73 */
Saurav Dasfbe25c52015-03-04 11:12:00 -080074 DEC_MPLS_TTL,
sangho3f97a17d2015-01-29 22:56:29 -080075
Saurav Dasfbe25c52015-03-04 11:12:00 -080076 /**
77 * VLAN Pop modification.
78 */
Jonathan Hart54b406b2015-03-06 16:24:14 -080079 VLAN_POP,
80
81 /**
82 * VLAN Push modification.
83 */
Hyunsun Moona08c5d02015-07-14 17:53:00 -070084 VLAN_PUSH,
85
86 /**
Saurav Das73a7dd42015-08-19 22:20:31 -070087 * Tunnel id modification.
Hyunsun Moona08c5d02015-07-14 17:53:00 -070088 */
Saurav Das73a7dd42015-08-19 22:20:31 -070089 TUNNEL_ID,
90
91 /**
92 * MPLS BOS instruction.
93 */
94 MPLS_BOS
alshabib55a55d92014-09-16 11:59:31 -070095 }
96
97 // TODO: Create factory class 'Instructions' that will have various factory
98 // to create specific instructions.
99
alshabib35edb1a2014-09-16 17:44:44 -0700100 public abstract L2SubType subtype();
alshabib55a55d92014-09-16 11:59:31 -0700101
102 @Override
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800103 public final Type type() {
alshabib35edb1a2014-09-16 17:44:44 -0700104 return Type.L2MODIFICATION;
alshabib55a55d92014-09-16 11:59:31 -0700105 }
106
107 /**
108 * Represents a L2 src/dst modification instruction.
109 */
110 public static final class ModEtherInstruction extends L2ModificationInstruction {
111
alshabib35edb1a2014-09-16 17:44:44 -0700112 private final L2SubType subtype;
Ayaka Koshibea9c199f2014-09-16 16:21:40 -0700113 private final MacAddress mac;
alshabib55a55d92014-09-16 11:59:31 -0700114
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800115 ModEtherInstruction(L2SubType subType, MacAddress addr) {
alshabib64231f62014-09-16 17:58:36 -0700116
alshabib55a55d92014-09-16 11:59:31 -0700117 this.subtype = subType;
118 this.mac = addr;
119 }
120
121 @Override
alshabib35edb1a2014-09-16 17:44:44 -0700122 public L2SubType subtype() {
alshabib55a55d92014-09-16 11:59:31 -0700123 return this.subtype;
124 }
125
Ayaka Koshibea9c199f2014-09-16 16:21:40 -0700126 public MacAddress mac() {
alshabib55a55d92014-09-16 11:59:31 -0700127 return this.mac;
128 }
129
alshabib99b8fdc2014-09-25 14:30:22 -0700130 @Override
131 public String toString() {
132 return toStringHelper(subtype().toString())
133 .add("mac", mac).toString();
134 }
135
alshabib8ca53902014-10-07 13:11:17 -0700136 @Override
137 public int hashCode() {
Thomas Vachuska9b2da212014-11-10 19:30:25 -0800138 return Objects.hash(type(), subtype, mac);
alshabib8ca53902014-10-07 13:11:17 -0700139 }
140
141 @Override
142 public boolean equals(Object obj) {
143 if (this == obj) {
144 return true;
145 }
146 if (obj instanceof ModEtherInstruction) {
147 ModEtherInstruction that = (ModEtherInstruction) obj;
148 return Objects.equals(mac, that.mac) &&
149 Objects.equals(subtype, that.subtype);
alshabib8ca53902014-10-07 13:11:17 -0700150 }
151 return false;
152 }
alshabib55a55d92014-09-16 11:59:31 -0700153 }
154
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800155 // TODO This instruction is reused for Pop-Mpls. Consider renaming.
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800156 public static final class PushHeaderInstructions extends
157 L2ModificationInstruction {
158
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800159
alshabib7b808c52015-06-26 14:22:24 -0700160 private final L2SubType subtype;
161 private final EthType ethernetType; // Ethernet type value: 16 bits
162
163 PushHeaderInstructions(L2SubType subType, EthType ethernetType) {
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800164 this.subtype = subType;
alshabib7b808c52015-06-26 14:22:24 -0700165 this.ethernetType = ethernetType;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800166 }
167
alshabib7b808c52015-06-26 14:22:24 -0700168 public EthType ethernetType() {
alshabib0ad43982015-05-07 13:43:13 -0700169 return ethernetType;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800170 }
171
172 @Override
173 public L2SubType subtype() {
174 return this.subtype;
175 }
176
177 @Override
178 public String toString() {
Yuta HIGUCHI32a53c52015-02-08 01:25:40 -0800179 return toStringHelper(subtype().toString())
alshabib7b808c52015-06-26 14:22:24 -0700180 .add("ethernetType", ethernetType())
Yuta HIGUCHI32a53c52015-02-08 01:25:40 -0800181 .toString();
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800182 }
183
184 @Override
185 public int hashCode() {
Yuta HIGUCHI32a53c52015-02-08 01:25:40 -0800186 return Objects.hash(type(), subtype, ethernetType);
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800187 }
188
189 @Override
190 public boolean equals(Object obj) {
191 if (this == obj) {
192 return true;
193 }
194 if (obj instanceof PushHeaderInstructions) {
195 PushHeaderInstructions that = (PushHeaderInstructions) obj;
Yuta HIGUCHI32a53c52015-02-08 01:25:40 -0800196 return Objects.equals(subtype, that.subtype) &&
197 Objects.equals(this.ethernetType, that.ethernetType);
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800198 }
199 return false;
200 }
201 }
202
203
204
alshabib55a55d92014-09-16 11:59:31 -0700205 /**
alshabib55a55d92014-09-16 11:59:31 -0700206 * Represents a VLAN id modification instruction.
207 */
208 public static final class ModVlanIdInstruction extends L2ModificationInstruction {
209
Ray Milkey78081052014-11-05 10:38:12 -0800210 private final VlanId vlanId;
alshabib55a55d92014-09-16 11:59:31 -0700211
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800212 ModVlanIdInstruction(VlanId vlanId) {
alshabib55a55d92014-09-16 11:59:31 -0700213 this.vlanId = vlanId;
214 }
215
216 @Override
alshabib35edb1a2014-09-16 17:44:44 -0700217 public L2SubType subtype() {
alshabib7410fea2014-09-16 13:48:39 -0700218 return L2SubType.VLAN_ID;
alshabib55a55d92014-09-16 11:59:31 -0700219 }
220
Ayaka Koshibea9c199f2014-09-16 16:21:40 -0700221 public VlanId vlanId() {
alshabib55a55d92014-09-16 11:59:31 -0700222 return this.vlanId;
223 }
224
alshabib99b8fdc2014-09-25 14:30:22 -0700225 @Override
226 public String toString() {
227 return toStringHelper(subtype().toString())
228 .add("id", vlanId).toString();
229 }
230
alshabib8ca53902014-10-07 13:11:17 -0700231 @Override
232 public int hashCode() {
Thomas Vachuska9b2da212014-11-10 19:30:25 -0800233 return Objects.hash(type(), subtype(), vlanId);
alshabib8ca53902014-10-07 13:11:17 -0700234 }
235
236 @Override
237 public boolean equals(Object obj) {
238 if (this == obj) {
239 return true;
240 }
241 if (obj instanceof ModVlanIdInstruction) {
242 ModVlanIdInstruction that = (ModVlanIdInstruction) obj;
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800243 return Objects.equals(vlanId, that.vlanId);
alshabib8ca53902014-10-07 13:11:17 -0700244 }
245 return false;
246 }
alshabib55a55d92014-09-16 11:59:31 -0700247 }
248
alshabib7410fea2014-09-16 13:48:39 -0700249 /**
250 * Represents a VLAN PCP modification instruction.
251 */
252 public static final class ModVlanPcpInstruction extends L2ModificationInstruction {
253
alshabib0ad43982015-05-07 13:43:13 -0700254 private static final byte MASK = 0x7;
255 private final byte vlanPcp;
alshabib7410fea2014-09-16 13:48:39 -0700256
alshabib0ad43982015-05-07 13:43:13 -0700257 ModVlanPcpInstruction(byte vlanPcp) {
258 this.vlanPcp = (byte) (vlanPcp & MASK);
alshabib7410fea2014-09-16 13:48:39 -0700259 }
260
261 @Override
alshabib35edb1a2014-09-16 17:44:44 -0700262 public L2SubType subtype() {
alshabib7410fea2014-09-16 13:48:39 -0700263 return L2SubType.VLAN_PCP;
264 }
265
alshabib0ad43982015-05-07 13:43:13 -0700266 public byte vlanPcp() {
alshabib7410fea2014-09-16 13:48:39 -0700267 return this.vlanPcp;
268 }
269
alshabib99b8fdc2014-09-25 14:30:22 -0700270 @Override
271 public String toString() {
272 return toStringHelper(subtype().toString())
273 .add("pcp", Long.toHexString(vlanPcp)).toString();
274 }
275
alshabib8ca53902014-10-07 13:11:17 -0700276 @Override
277 public int hashCode() {
Thomas Vachuska9b2da212014-11-10 19:30:25 -0800278 return Objects.hash(type(), subtype(), vlanPcp);
alshabib8ca53902014-10-07 13:11:17 -0700279 }
280
281 @Override
282 public boolean equals(Object obj) {
283 if (this == obj) {
284 return true;
285 }
286 if (obj instanceof ModVlanPcpInstruction) {
287 ModVlanPcpInstruction that = (ModVlanPcpInstruction) obj;
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800288 return Objects.equals(vlanPcp, that.vlanPcp);
alshabib8ca53902014-10-07 13:11:17 -0700289 }
290 return false;
291 }
alshabib7410fea2014-09-16 13:48:39 -0700292 }
293
Saurav Dasfbe25c52015-03-04 11:12:00 -0800294 /**
295 * Represents a VLAN POP modification instruction.
296 */
297 public static final class PopVlanInstruction extends L2ModificationInstruction {
298 private final L2SubType subtype;
299
300 PopVlanInstruction(L2SubType subType) {
301 this.subtype = subType;
302 }
303
304 @Override
305 public L2SubType subtype() {
306 return subtype;
307 }
308
309 @Override
310 public String toString() {
311 return toStringHelper(subtype().toString())
312 .toString();
313 }
314
315 @Override
316 public int hashCode() {
317 return Objects.hash(type(), subtype);
318 }
319
320 @Override
321 public boolean equals(Object obj) {
322 if (this == obj) {
323 return true;
324 }
HIGUCHI Yuta7bb8b3f2015-03-13 23:21:37 -0700325 if (obj instanceof PopVlanInstruction) {
326 PopVlanInstruction that = (PopVlanInstruction) obj;
Saurav Dasfbe25c52015-03-04 11:12:00 -0800327 return Objects.equals(subtype, that.subtype);
328 }
329 return false;
330 }
331 }
alshabib55a55d92014-09-16 11:59:31 -0700332
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800333 /**
334 * Represents a MPLS label modification.
335 */
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800336 public static final class ModMplsLabelInstruction
337 extends L2ModificationInstruction {
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800338
Michele Santuari4b6019e2014-12-19 11:31:45 +0100339 private final MplsLabel mplsLabel;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800340
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800341 ModMplsLabelInstruction(MplsLabel mplsLabel) {
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800342 this.mplsLabel = mplsLabel;
343 }
344
HIGUCHI Yuta04b49fc2015-08-28 09:58:58 -0700345 /**
346 * @deprecated in Drake Release.
347 */
348 // Consider changing return value to MplsLabel
349 // after deprecation process so that it'll be symmetric to
350 // MplsCriterion#label()
351 @Deprecated
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800352 public Integer label() {
Michele Santuari4b6019e2014-12-19 11:31:45 +0100353 return mplsLabel.toInt();
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800354 }
355
HIGUCHI Yuta60db9772015-08-26 17:49:34 -0700356 public MplsLabel mplsLabel() {
357 return mplsLabel;
358 }
359
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800360 @Override
361 public L2SubType subtype() {
362 return L2SubType.MPLS_LABEL;
363 }
364
365 @Override
366 public String toString() {
Pavlin Radoslavov3ebe1702015-02-17 09:53:17 -0800367 return toStringHelper(subtype().toString())
Michele Santuari4b6019e2014-12-19 11:31:45 +0100368 .add("mpls", mplsLabel).toString();
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800369 }
370
371 @Override
372 public int hashCode() {
Yuta HIGUCHIcca5e722015-02-05 14:00:41 -0800373 return Objects.hash(type(), subtype(), mplsLabel);
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800374 }
375
376 @Override
377 public boolean equals(Object obj) {
378 if (this == obj) {
379 return true;
380 }
381 if (obj instanceof ModMplsLabelInstruction) {
382 ModMplsLabelInstruction that = (ModMplsLabelInstruction) obj;
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800383 return Objects.equals(mplsLabel, that.mplsLabel);
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800384 }
385 return false;
386 }
387 }
sangho3f97a17d2015-01-29 22:56:29 -0800388
389 /**
Saurav Das73a7dd42015-08-19 22:20:31 -0700390 * Represents a MPLS BOS modification.
391 */
392 public static final class ModMplsBosInstruction
393 extends L2ModificationInstruction {
394
395 private final boolean mplsBos;
396
397 ModMplsBosInstruction(boolean mplsBos) {
398 this.mplsBos = mplsBos;
399 }
400
401 public boolean mplsBos() {
402 return mplsBos;
403 }
404
405 @Override
406 public L2SubType subtype() {
407 return L2SubType.MPLS_BOS;
408 }
409
410 @Override
411 public String toString() {
412 return toStringHelper(subtype().toString()).add("bos", mplsBos)
413 .toString();
414 }
415
416 @Override
417 public int hashCode() {
418 return Objects.hash(type(), subtype(), mplsBos);
419 }
420
421 @Override
422 public boolean equals(Object obj) {
423 if (this == obj) {
424 return true;
425 }
426 if (obj instanceof ModMplsBosInstruction) {
427 ModMplsBosInstruction that = (ModMplsBosInstruction) obj;
428 return Objects.equals(mplsBos, that.mplsBos());
429 }
430 return false;
431 }
432 }
433
434 /**
Yuta HIGUCHIcca5e722015-02-05 14:00:41 -0800435 * Represents a MPLS TTL modification.
sangho3f97a17d2015-01-29 22:56:29 -0800436 */
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800437 public static final class ModMplsTtlInstruction
438 extends L2ModificationInstruction {
sangho3f97a17d2015-01-29 22:56:29 -0800439
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800440 ModMplsTtlInstruction() {
sangho3f97a17d2015-01-29 22:56:29 -0800441 }
442
443 @Override
444 public L2SubType subtype() {
445 return L2SubType.DEC_MPLS_TTL;
446 }
447
448 @Override
449 public String toString() {
Yuta HIGUCHIcca5e722015-02-05 14:00:41 -0800450 return toStringHelper(subtype().toString())
451 .toString();
sangho3f97a17d2015-01-29 22:56:29 -0800452 }
453
454 @Override
455 public int hashCode() {
Yuta HIGUCHIcca5e722015-02-05 14:00:41 -0800456 return Objects.hash(type(), subtype());
sangho3f97a17d2015-01-29 22:56:29 -0800457 }
458
459 @Override
460 public boolean equals(Object obj) {
461 if (this == obj) {
462 return true;
463 }
Yuta HIGUCHIcca5e722015-02-05 14:00:41 -0800464 if (obj instanceof ModMplsTtlInstruction) {
465 return true;
sangho3f97a17d2015-01-29 22:56:29 -0800466 }
467 return false;
468 }
469 }
Hyunsun Moona08c5d02015-07-14 17:53:00 -0700470
471 /**
472 * Represents a Tunnel id modification.
473 */
474 public static final class ModTunnelIdInstruction
475 extends L2ModificationInstruction {
476
477 private final long tunnelId;
478
479 ModTunnelIdInstruction(long tunnelId) {
480 this.tunnelId = tunnelId;
481 }
482
483 public long tunnelId() {
484 return this.tunnelId;
485 }
486
487 @Override
488 public L2SubType subtype() {
489 return L2SubType.TUNNEL_ID;
490 }
491
492 @Override
493 public String toString() {
494 return toStringHelper(subtype().toString())
495 .add("id", Long.toHexString(tunnelId))
496 .toString();
497 }
498
499 @Override
500 public int hashCode() {
501 return Objects.hash(type(), subtype(), tunnelId);
502 }
503
504 @Override
505 public boolean equals(Object obj) {
506 if (this == obj) {
507 return true;
508 }
509 if (obj instanceof ModTunnelIdInstruction) {
510 ModTunnelIdInstruction that = (ModTunnelIdInstruction) obj;
511 return Objects.equals(tunnelId, that.tunnelId);
512 }
513 return false;
514 }
515 }
alshabib55a55d92014-09-16 11:59:31 -0700516}