blob: cf6a1a2ccdefd6ca312f6b60ec7f3aa9141d86c4 [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
345 public Integer label() {
Michele Santuari4b6019e2014-12-19 11:31:45 +0100346 return mplsLabel.toInt();
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800347 }
348
349 @Override
350 public L2SubType subtype() {
351 return L2SubType.MPLS_LABEL;
352 }
353
354 @Override
355 public String toString() {
Pavlin Radoslavov3ebe1702015-02-17 09:53:17 -0800356 return toStringHelper(subtype().toString())
Michele Santuari4b6019e2014-12-19 11:31:45 +0100357 .add("mpls", mplsLabel).toString();
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800358 }
359
360 @Override
361 public int hashCode() {
Yuta HIGUCHIcca5e722015-02-05 14:00:41 -0800362 return Objects.hash(type(), subtype(), mplsLabel);
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800363 }
364
365 @Override
366 public boolean equals(Object obj) {
367 if (this == obj) {
368 return true;
369 }
370 if (obj instanceof ModMplsLabelInstruction) {
371 ModMplsLabelInstruction that = (ModMplsLabelInstruction) obj;
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800372 return Objects.equals(mplsLabel, that.mplsLabel);
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800373 }
374 return false;
375 }
376 }
sangho3f97a17d2015-01-29 22:56:29 -0800377
378 /**
Saurav Das73a7dd42015-08-19 22:20:31 -0700379 * Represents a MPLS BOS modification.
380 */
381 public static final class ModMplsBosInstruction
382 extends L2ModificationInstruction {
383
384 private final boolean mplsBos;
385
386 ModMplsBosInstruction(boolean mplsBos) {
387 this.mplsBos = mplsBos;
388 }
389
390 public boolean mplsBos() {
391 return mplsBos;
392 }
393
394 @Override
395 public L2SubType subtype() {
396 return L2SubType.MPLS_BOS;
397 }
398
399 @Override
400 public String toString() {
401 return toStringHelper(subtype().toString()).add("bos", mplsBos)
402 .toString();
403 }
404
405 @Override
406 public int hashCode() {
407 return Objects.hash(type(), subtype(), mplsBos);
408 }
409
410 @Override
411 public boolean equals(Object obj) {
412 if (this == obj) {
413 return true;
414 }
415 if (obj instanceof ModMplsBosInstruction) {
416 ModMplsBosInstruction that = (ModMplsBosInstruction) obj;
417 return Objects.equals(mplsBos, that.mplsBos());
418 }
419 return false;
420 }
421 }
422
423 /**
Yuta HIGUCHIcca5e722015-02-05 14:00:41 -0800424 * Represents a MPLS TTL modification.
sangho3f97a17d2015-01-29 22:56:29 -0800425 */
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800426 public static final class ModMplsTtlInstruction
427 extends L2ModificationInstruction {
sangho3f97a17d2015-01-29 22:56:29 -0800428
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800429 ModMplsTtlInstruction() {
sangho3f97a17d2015-01-29 22:56:29 -0800430 }
431
432 @Override
433 public L2SubType subtype() {
434 return L2SubType.DEC_MPLS_TTL;
435 }
436
437 @Override
438 public String toString() {
Yuta HIGUCHIcca5e722015-02-05 14:00:41 -0800439 return toStringHelper(subtype().toString())
440 .toString();
sangho3f97a17d2015-01-29 22:56:29 -0800441 }
442
443 @Override
444 public int hashCode() {
Yuta HIGUCHIcca5e722015-02-05 14:00:41 -0800445 return Objects.hash(type(), subtype());
sangho3f97a17d2015-01-29 22:56:29 -0800446 }
447
448 @Override
449 public boolean equals(Object obj) {
450 if (this == obj) {
451 return true;
452 }
Yuta HIGUCHIcca5e722015-02-05 14:00:41 -0800453 if (obj instanceof ModMplsTtlInstruction) {
454 return true;
sangho3f97a17d2015-01-29 22:56:29 -0800455 }
456 return false;
457 }
458 }
Hyunsun Moona08c5d02015-07-14 17:53:00 -0700459
460 /**
461 * Represents a Tunnel id modification.
462 */
463 public static final class ModTunnelIdInstruction
464 extends L2ModificationInstruction {
465
466 private final long tunnelId;
467
468 ModTunnelIdInstruction(long tunnelId) {
469 this.tunnelId = tunnelId;
470 }
471
472 public long tunnelId() {
473 return this.tunnelId;
474 }
475
476 @Override
477 public L2SubType subtype() {
478 return L2SubType.TUNNEL_ID;
479 }
480
481 @Override
482 public String toString() {
483 return toStringHelper(subtype().toString())
484 .add("id", Long.toHexString(tunnelId))
485 .toString();
486 }
487
488 @Override
489 public int hashCode() {
490 return Objects.hash(type(), subtype(), tunnelId);
491 }
492
493 @Override
494 public boolean equals(Object obj) {
495 if (this == obj) {
496 return true;
497 }
498 if (obj instanceof ModTunnelIdInstruction) {
499 ModTunnelIdInstruction that = (ModTunnelIdInstruction) obj;
500 return Objects.equals(tunnelId, that.tunnelId);
501 }
502 return false;
503 }
504 }
alshabib55a55d92014-09-16 11:59:31 -0700505}