blob: 31bd2c0d9843605e762255af194fe1f7f33bd6c1 [file] [log] [blame]
Thomas Vachuska83e090e2014-10-22 14:25:35 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2014-present 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
alshabib55a55d92014-09-16 11:59:31 -070025/**
26 * Abstraction of a single traffic treatment step.
alshabib55a55d92014-09-16 11:59:31 -070027 */
28public abstract class L2ModificationInstruction implements Instruction {
29
Jonathan Hartc7840bd2016-01-21 23:26:29 -080030 private static final String SEPARATOR = ":";
31
alshabib55a55d92014-09-16 11:59:31 -070032 /**
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
alshabib35edb1a2014-09-16 17:44:44 -070097 public abstract L2SubType subtype();
alshabib55a55d92014-09-16 11:59:31 -070098
99 @Override
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800100 public final Type type() {
alshabib35edb1a2014-09-16 17:44:44 -0700101 return Type.L2MODIFICATION;
alshabib55a55d92014-09-16 11:59:31 -0700102 }
103
104 /**
105 * Represents a L2 src/dst modification instruction.
106 */
107 public static final class ModEtherInstruction extends L2ModificationInstruction {
108
alshabib35edb1a2014-09-16 17:44:44 -0700109 private final L2SubType subtype;
Ayaka Koshibea9c199f2014-09-16 16:21:40 -0700110 private final MacAddress mac;
alshabib55a55d92014-09-16 11:59:31 -0700111
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800112 ModEtherInstruction(L2SubType subType, MacAddress addr) {
alshabib64231f62014-09-16 17:58:36 -0700113
alshabib55a55d92014-09-16 11:59:31 -0700114 this.subtype = subType;
115 this.mac = addr;
116 }
117
118 @Override
alshabib35edb1a2014-09-16 17:44:44 -0700119 public L2SubType subtype() {
alshabib55a55d92014-09-16 11:59:31 -0700120 return this.subtype;
121 }
122
Ayaka Koshibea9c199f2014-09-16 16:21:40 -0700123 public MacAddress mac() {
alshabib55a55d92014-09-16 11:59:31 -0700124 return this.mac;
125 }
126
alshabib99b8fdc2014-09-25 14:30:22 -0700127 @Override
128 public String toString() {
Jonathan Hartc7840bd2016-01-21 23:26:29 -0800129 return subtype().toString() + SEPARATOR + mac;
alshabib99b8fdc2014-09-25 14:30:22 -0700130 }
131
alshabib8ca53902014-10-07 13:11:17 -0700132 @Override
133 public int hashCode() {
Thomas Vachuska9b2da212014-11-10 19:30:25 -0800134 return Objects.hash(type(), subtype, mac);
alshabib8ca53902014-10-07 13:11:17 -0700135 }
136
137 @Override
138 public boolean equals(Object obj) {
139 if (this == obj) {
140 return true;
141 }
142 if (obj instanceof ModEtherInstruction) {
143 ModEtherInstruction that = (ModEtherInstruction) obj;
144 return Objects.equals(mac, that.mac) &&
145 Objects.equals(subtype, that.subtype);
alshabib8ca53902014-10-07 13:11:17 -0700146 }
147 return false;
148 }
alshabib55a55d92014-09-16 11:59:31 -0700149 }
150
Jian Liddfd2eb2016-05-19 11:32:18 -0700151 /**
Jian Liddfd2eb2016-05-19 11:32:18 -0700152 * Represents a MPLS header modification instruction.
153 */
154 public static final class ModMplsHeaderInstruction extends L2ModificationInstruction {
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800155
Jian Liddfd2eb2016-05-19 11:32:18 -0700156 private final L2SubType subtype;
157 private final EthType ethernetType; // Ethernet type value: 16 bits
158
159 ModMplsHeaderInstruction(L2SubType subType, EthType ethernetType) {
160 this.subtype = subType;
161 this.ethernetType = ethernetType;
162 }
163
164 public EthType ethernetType() {
165 return ethernetType;
166 }
167
168 @Override
169 public L2SubType subtype() {
170 return subtype;
171 }
172
173 @Override
174 public String toString() {
175 return subtype().toString() + SEPARATOR + ethernetType;
176 }
177
178 @Override
179 public int hashCode() {
180 return Objects.hash(type(), subtype, ethernetType);
181 }
182
183 @Override
184 public boolean equals(Object obj) {
185 if (this == obj) {
186 return true;
187 }
188 if (obj instanceof ModMplsHeaderInstruction) {
189 ModMplsHeaderInstruction that = (ModMplsHeaderInstruction) obj;
190 return Objects.equals(subtype, that.subtype) &&
191 Objects.equals(this.ethernetType, that.ethernetType);
192 }
193 return false;
194 }
195 }
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800196
alshabib55a55d92014-09-16 11:59:31 -0700197 /**
alshabib55a55d92014-09-16 11:59:31 -0700198 * Represents a VLAN id modification instruction.
199 */
200 public static final class ModVlanIdInstruction extends L2ModificationInstruction {
201
Ray Milkey78081052014-11-05 10:38:12 -0800202 private final VlanId vlanId;
alshabib55a55d92014-09-16 11:59:31 -0700203
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800204 ModVlanIdInstruction(VlanId vlanId) {
alshabib55a55d92014-09-16 11:59:31 -0700205 this.vlanId = vlanId;
206 }
207
208 @Override
alshabib35edb1a2014-09-16 17:44:44 -0700209 public L2SubType subtype() {
alshabib7410fea2014-09-16 13:48:39 -0700210 return L2SubType.VLAN_ID;
alshabib55a55d92014-09-16 11:59:31 -0700211 }
212
Ayaka Koshibea9c199f2014-09-16 16:21:40 -0700213 public VlanId vlanId() {
alshabib55a55d92014-09-16 11:59:31 -0700214 return this.vlanId;
215 }
216
alshabib99b8fdc2014-09-25 14:30:22 -0700217 @Override
218 public String toString() {
Jonathan Hartc7840bd2016-01-21 23:26:29 -0800219 return subtype().toString() + SEPARATOR + vlanId;
alshabib99b8fdc2014-09-25 14:30:22 -0700220 }
221
alshabib8ca53902014-10-07 13:11:17 -0700222 @Override
223 public int hashCode() {
Thomas Vachuska9b2da212014-11-10 19:30:25 -0800224 return Objects.hash(type(), subtype(), vlanId);
alshabib8ca53902014-10-07 13:11:17 -0700225 }
226
227 @Override
228 public boolean equals(Object obj) {
229 if (this == obj) {
230 return true;
231 }
232 if (obj instanceof ModVlanIdInstruction) {
233 ModVlanIdInstruction that = (ModVlanIdInstruction) obj;
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800234 return Objects.equals(vlanId, that.vlanId);
alshabib8ca53902014-10-07 13:11:17 -0700235 }
236 return false;
237 }
alshabib55a55d92014-09-16 11:59:31 -0700238 }
239
alshabib7410fea2014-09-16 13:48:39 -0700240 /**
241 * Represents a VLAN PCP modification instruction.
242 */
243 public static final class ModVlanPcpInstruction extends L2ModificationInstruction {
244
alshabib0ad43982015-05-07 13:43:13 -0700245 private static final byte MASK = 0x7;
246 private final byte vlanPcp;
alshabib7410fea2014-09-16 13:48:39 -0700247
alshabib0ad43982015-05-07 13:43:13 -0700248 ModVlanPcpInstruction(byte vlanPcp) {
249 this.vlanPcp = (byte) (vlanPcp & MASK);
alshabib7410fea2014-09-16 13:48:39 -0700250 }
251
252 @Override
alshabib35edb1a2014-09-16 17:44:44 -0700253 public L2SubType subtype() {
alshabib7410fea2014-09-16 13:48:39 -0700254 return L2SubType.VLAN_PCP;
255 }
256
alshabib0ad43982015-05-07 13:43:13 -0700257 public byte vlanPcp() {
alshabib7410fea2014-09-16 13:48:39 -0700258 return this.vlanPcp;
259 }
260
alshabib99b8fdc2014-09-25 14:30:22 -0700261 @Override
262 public String toString() {
Jonathan Hartc7840bd2016-01-21 23:26:29 -0800263 return subtype().toString() + SEPARATOR + Long.toHexString(vlanPcp);
alshabib99b8fdc2014-09-25 14:30:22 -0700264 }
265
alshabib8ca53902014-10-07 13:11:17 -0700266 @Override
267 public int hashCode() {
Thomas Vachuska9b2da212014-11-10 19:30:25 -0800268 return Objects.hash(type(), subtype(), vlanPcp);
alshabib8ca53902014-10-07 13:11:17 -0700269 }
270
271 @Override
272 public boolean equals(Object obj) {
273 if (this == obj) {
274 return true;
275 }
276 if (obj instanceof ModVlanPcpInstruction) {
277 ModVlanPcpInstruction that = (ModVlanPcpInstruction) obj;
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800278 return Objects.equals(vlanPcp, that.vlanPcp);
alshabib8ca53902014-10-07 13:11:17 -0700279 }
280 return false;
281 }
alshabib7410fea2014-09-16 13:48:39 -0700282 }
283
Saurav Dasfbe25c52015-03-04 11:12:00 -0800284 /**
Jian Liddfd2eb2016-05-19 11:32:18 -0700285 * Represents a VLAN Header modification instruction.
286 */
287 public static final class ModVlanHeaderInstruction extends L2ModificationInstruction {
288
289 private final L2SubType subtype;
290 private EthType ethernetType; // Ethernet type value: 16 bits
291
292 ModVlanHeaderInstruction(L2SubType subType, EthType ethernetType) {
293 this.subtype = subType;
294 this.ethernetType = ethernetType;
295 }
296
297 ModVlanHeaderInstruction(L2SubType subType) {
298 this(subType, EthType.EtherType.UNKNOWN.ethType());
299 }
300
301 public EthType ethernetType() {
302 return ethernetType;
303 }
304
305 @Override
306 public L2SubType subtype() {
307 return subtype;
308 }
309
310 @Override
311 public String toString() {
Charles Chancefcf772017-01-22 13:53:13 -0800312 // etherType is not specified in VLAN_POP case. Ignore it.
313 return subtype().equals(L2SubType.VLAN_POP) ?
314 subtype().toString() :
315 subtype().toString() + SEPARATOR + ethernetType;
Jian Liddfd2eb2016-05-19 11:32:18 -0700316 }
317
318 @Override
319 public int hashCode() {
320 return Objects.hash(type(), subtype, ethernetType);
321 }
322
323 @Override
324 public boolean equals(Object obj) {
325 if (this == obj) {
326 return true;
327 }
328 if (obj instanceof ModVlanHeaderInstruction) {
329 ModVlanHeaderInstruction that = (ModVlanHeaderInstruction) obj;
330 return Objects.equals(subtype, that.subtype) &&
331 Objects.equals(this.ethernetType, that.ethernetType);
332 }
333 return false;
334 }
335 }
336
337 /**
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800338 * Represents a MPLS label modification.
339 */
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800340 public static final class ModMplsLabelInstruction
341 extends L2ModificationInstruction {
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800342
Michele Santuari4b6019e2014-12-19 11:31:45 +0100343 private final MplsLabel mplsLabel;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800344
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800345 ModMplsLabelInstruction(MplsLabel mplsLabel) {
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800346 this.mplsLabel = mplsLabel;
347 }
348
Ray Milkey125572b2016-02-22 16:48:17 -0800349 public MplsLabel label() {
350 return mplsLabel;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800351 }
352
Ray Milkey125572b2016-02-22 16:48:17 -0800353 /**
354 * Extracts the MPLS label from the instruction.
355 *
356 * @return MPLS label
357 * @deprecated deprecated in 1.5.0 Falcon
358 */
359 @Deprecated
HIGUCHI Yuta60db9772015-08-26 17:49:34 -0700360 public MplsLabel mplsLabel() {
Ray Milkey125572b2016-02-22 16:48:17 -0800361 return label();
HIGUCHI Yuta60db9772015-08-26 17:49:34 -0700362 }
363
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800364 @Override
365 public L2SubType subtype() {
366 return L2SubType.MPLS_LABEL;
367 }
368
369 @Override
370 public String toString() {
Jonathan Hartc7840bd2016-01-21 23:26:29 -0800371 return subtype().toString() + SEPARATOR + mplsLabel;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800372 }
373
374 @Override
375 public int hashCode() {
Yuta HIGUCHIcca5e722015-02-05 14:00:41 -0800376 return Objects.hash(type(), subtype(), mplsLabel);
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800377 }
378
379 @Override
380 public boolean equals(Object obj) {
381 if (this == obj) {
382 return true;
383 }
384 if (obj instanceof ModMplsLabelInstruction) {
385 ModMplsLabelInstruction that = (ModMplsLabelInstruction) obj;
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800386 return Objects.equals(mplsLabel, that.mplsLabel);
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800387 }
388 return false;
389 }
390 }
sangho3f97a17d2015-01-29 22:56:29 -0800391
392 /**
Saurav Das73a7dd42015-08-19 22:20:31 -0700393 * Represents a MPLS BOS modification.
394 */
395 public static final class ModMplsBosInstruction
396 extends L2ModificationInstruction {
397
398 private final boolean mplsBos;
399
400 ModMplsBosInstruction(boolean mplsBos) {
401 this.mplsBos = mplsBos;
402 }
403
404 public boolean mplsBos() {
405 return mplsBos;
406 }
407
408 @Override
409 public L2SubType subtype() {
410 return L2SubType.MPLS_BOS;
411 }
412
413 @Override
414 public String toString() {
Jonathan Hartc7840bd2016-01-21 23:26:29 -0800415 return subtype().toString() + SEPARATOR + mplsBos;
Saurav Das73a7dd42015-08-19 22:20:31 -0700416 }
417
418 @Override
419 public int hashCode() {
420 return Objects.hash(type(), subtype(), mplsBos);
421 }
422
423 @Override
424 public boolean equals(Object obj) {
425 if (this == obj) {
426 return true;
427 }
428 if (obj instanceof ModMplsBosInstruction) {
429 ModMplsBosInstruction that = (ModMplsBosInstruction) obj;
430 return Objects.equals(mplsBos, that.mplsBos());
431 }
432 return false;
433 }
434 }
435
436 /**
Yuta HIGUCHIcca5e722015-02-05 14:00:41 -0800437 * Represents a MPLS TTL modification.
sangho3f97a17d2015-01-29 22:56:29 -0800438 */
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800439 public static final class ModMplsTtlInstruction
440 extends L2ModificationInstruction {
sangho3f97a17d2015-01-29 22:56:29 -0800441
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800442 ModMplsTtlInstruction() {
sangho3f97a17d2015-01-29 22:56:29 -0800443 }
444
445 @Override
446 public L2SubType subtype() {
447 return L2SubType.DEC_MPLS_TTL;
448 }
449
450 @Override
451 public String toString() {
Jonathan Hartc7840bd2016-01-21 23:26:29 -0800452 return subtype().toString();
sangho3f97a17d2015-01-29 22:56:29 -0800453 }
454
455 @Override
456 public int hashCode() {
Yuta HIGUCHIcca5e722015-02-05 14:00:41 -0800457 return Objects.hash(type(), subtype());
sangho3f97a17d2015-01-29 22:56:29 -0800458 }
459
460 @Override
461 public boolean equals(Object obj) {
462 if (this == obj) {
463 return true;
464 }
Yuta HIGUCHIcca5e722015-02-05 14:00:41 -0800465 if (obj instanceof ModMplsTtlInstruction) {
466 return true;
sangho3f97a17d2015-01-29 22:56:29 -0800467 }
468 return false;
469 }
470 }
Hyunsun Moona08c5d02015-07-14 17:53:00 -0700471
472 /**
473 * Represents a Tunnel id modification.
474 */
475 public static final class ModTunnelIdInstruction
476 extends L2ModificationInstruction {
477
478 private final long tunnelId;
479
480 ModTunnelIdInstruction(long tunnelId) {
481 this.tunnelId = tunnelId;
482 }
483
484 public long tunnelId() {
485 return this.tunnelId;
486 }
487
488 @Override
489 public L2SubType subtype() {
490 return L2SubType.TUNNEL_ID;
491 }
492
493 @Override
494 public String toString() {
Jonathan Hartc7840bd2016-01-21 23:26:29 -0800495 return subtype().toString() + SEPARATOR + Long.toHexString(tunnelId);
Hyunsun Moona08c5d02015-07-14 17:53:00 -0700496 }
497
498 @Override
499 public int hashCode() {
500 return Objects.hash(type(), subtype(), tunnelId);
501 }
502
503 @Override
504 public boolean equals(Object obj) {
505 if (this == obj) {
506 return true;
507 }
508 if (obj instanceof ModTunnelIdInstruction) {
509 ModTunnelIdInstruction that = (ModTunnelIdInstruction) obj;
510 return Objects.equals(tunnelId, that.tunnelId);
511 }
512 return false;
513 }
514 }
alshabib55a55d92014-09-16 11:59:31 -0700515}