blob: b4ec0d3f7bc20ab9e8a277b8131a47c0e8e09aad [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 Yuta60db9772015-08-26 17:49:34 -0700345 // might want to deprecate this in the long run
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800346 public Integer label() {
Michele Santuari4b6019e2014-12-19 11:31:45 +0100347 return mplsLabel.toInt();
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800348 }
349
HIGUCHI Yuta60db9772015-08-26 17:49:34 -0700350 public MplsLabel mplsLabel() {
351 return mplsLabel;
352 }
353
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800354 @Override
355 public L2SubType subtype() {
356 return L2SubType.MPLS_LABEL;
357 }
358
359 @Override
360 public String toString() {
Pavlin Radoslavov3ebe1702015-02-17 09:53:17 -0800361 return toStringHelper(subtype().toString())
Michele Santuari4b6019e2014-12-19 11:31:45 +0100362 .add("mpls", mplsLabel).toString();
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800363 }
364
365 @Override
366 public int hashCode() {
Yuta HIGUCHIcca5e722015-02-05 14:00:41 -0800367 return Objects.hash(type(), subtype(), mplsLabel);
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800368 }
369
370 @Override
371 public boolean equals(Object obj) {
372 if (this == obj) {
373 return true;
374 }
375 if (obj instanceof ModMplsLabelInstruction) {
376 ModMplsLabelInstruction that = (ModMplsLabelInstruction) obj;
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800377 return Objects.equals(mplsLabel, that.mplsLabel);
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800378 }
379 return false;
380 }
381 }
sangho3f97a17d2015-01-29 22:56:29 -0800382
383 /**
Saurav Das73a7dd42015-08-19 22:20:31 -0700384 * Represents a MPLS BOS modification.
385 */
386 public static final class ModMplsBosInstruction
387 extends L2ModificationInstruction {
388
389 private final boolean mplsBos;
390
391 ModMplsBosInstruction(boolean mplsBos) {
392 this.mplsBos = mplsBos;
393 }
394
395 public boolean mplsBos() {
396 return mplsBos;
397 }
398
399 @Override
400 public L2SubType subtype() {
401 return L2SubType.MPLS_BOS;
402 }
403
404 @Override
405 public String toString() {
406 return toStringHelper(subtype().toString()).add("bos", mplsBos)
407 .toString();
408 }
409
410 @Override
411 public int hashCode() {
412 return Objects.hash(type(), subtype(), mplsBos);
413 }
414
415 @Override
416 public boolean equals(Object obj) {
417 if (this == obj) {
418 return true;
419 }
420 if (obj instanceof ModMplsBosInstruction) {
421 ModMplsBosInstruction that = (ModMplsBosInstruction) obj;
422 return Objects.equals(mplsBos, that.mplsBos());
423 }
424 return false;
425 }
426 }
427
428 /**
Yuta HIGUCHIcca5e722015-02-05 14:00:41 -0800429 * Represents a MPLS TTL modification.
sangho3f97a17d2015-01-29 22:56:29 -0800430 */
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800431 public static final class ModMplsTtlInstruction
432 extends L2ModificationInstruction {
sangho3f97a17d2015-01-29 22:56:29 -0800433
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800434 ModMplsTtlInstruction() {
sangho3f97a17d2015-01-29 22:56:29 -0800435 }
436
437 @Override
438 public L2SubType subtype() {
439 return L2SubType.DEC_MPLS_TTL;
440 }
441
442 @Override
443 public String toString() {
Yuta HIGUCHIcca5e722015-02-05 14:00:41 -0800444 return toStringHelper(subtype().toString())
445 .toString();
sangho3f97a17d2015-01-29 22:56:29 -0800446 }
447
448 @Override
449 public int hashCode() {
Yuta HIGUCHIcca5e722015-02-05 14:00:41 -0800450 return Objects.hash(type(), subtype());
sangho3f97a17d2015-01-29 22:56:29 -0800451 }
452
453 @Override
454 public boolean equals(Object obj) {
455 if (this == obj) {
456 return true;
457 }
Yuta HIGUCHIcca5e722015-02-05 14:00:41 -0800458 if (obj instanceof ModMplsTtlInstruction) {
459 return true;
sangho3f97a17d2015-01-29 22:56:29 -0800460 }
461 return false;
462 }
463 }
Hyunsun Moona08c5d02015-07-14 17:53:00 -0700464
465 /**
466 * Represents a Tunnel id modification.
467 */
468 public static final class ModTunnelIdInstruction
469 extends L2ModificationInstruction {
470
471 private final long tunnelId;
472
473 ModTunnelIdInstruction(long tunnelId) {
474 this.tunnelId = tunnelId;
475 }
476
477 public long tunnelId() {
478 return this.tunnelId;
479 }
480
481 @Override
482 public L2SubType subtype() {
483 return L2SubType.TUNNEL_ID;
484 }
485
486 @Override
487 public String toString() {
488 return toStringHelper(subtype().toString())
489 .add("id", Long.toHexString(tunnelId))
490 .toString();
491 }
492
493 @Override
494 public int hashCode() {
495 return Objects.hash(type(), subtype(), tunnelId);
496 }
497
498 @Override
499 public boolean equals(Object obj) {
500 if (this == obj) {
501 return true;
502 }
503 if (obj instanceof ModTunnelIdInstruction) {
504 ModTunnelIdInstruction that = (ModTunnelIdInstruction) obj;
505 return Objects.equals(tunnelId, that.tunnelId);
506 }
507 return false;
508 }
509 }
alshabib55a55d92014-09-16 11:59:31 -0700510}