blob: b0ab2f0733d6838a914c96e36975d956ad9e3f15 [file] [log] [blame]
Thomas Vachuska83e090e2014-10-22 14:25:35 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2014-present Open Networking Foundation
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
353 @Override
354 public L2SubType subtype() {
355 return L2SubType.MPLS_LABEL;
356 }
357
358 @Override
359 public String toString() {
Jonathan Hartc7840bd2016-01-21 23:26:29 -0800360 return subtype().toString() + SEPARATOR + mplsLabel;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800361 }
362
363 @Override
364 public int hashCode() {
Yuta HIGUCHIcca5e722015-02-05 14:00:41 -0800365 return Objects.hash(type(), subtype(), mplsLabel);
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800366 }
367
368 @Override
369 public boolean equals(Object obj) {
370 if (this == obj) {
371 return true;
372 }
373 if (obj instanceof ModMplsLabelInstruction) {
374 ModMplsLabelInstruction that = (ModMplsLabelInstruction) obj;
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800375 return Objects.equals(mplsLabel, that.mplsLabel);
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800376 }
377 return false;
378 }
379 }
sangho3f97a17d2015-01-29 22:56:29 -0800380
381 /**
Saurav Das73a7dd42015-08-19 22:20:31 -0700382 * Represents a MPLS BOS modification.
383 */
384 public static final class ModMplsBosInstruction
385 extends L2ModificationInstruction {
386
387 private final boolean mplsBos;
388
389 ModMplsBosInstruction(boolean mplsBos) {
390 this.mplsBos = mplsBos;
391 }
392
393 public boolean mplsBos() {
394 return mplsBos;
395 }
396
397 @Override
398 public L2SubType subtype() {
399 return L2SubType.MPLS_BOS;
400 }
401
402 @Override
403 public String toString() {
Jonathan Hartc7840bd2016-01-21 23:26:29 -0800404 return subtype().toString() + SEPARATOR + mplsBos;
Saurav Das73a7dd42015-08-19 22:20:31 -0700405 }
406
407 @Override
408 public int hashCode() {
409 return Objects.hash(type(), subtype(), mplsBos);
410 }
411
412 @Override
413 public boolean equals(Object obj) {
414 if (this == obj) {
415 return true;
416 }
417 if (obj instanceof ModMplsBosInstruction) {
418 ModMplsBosInstruction that = (ModMplsBosInstruction) obj;
419 return Objects.equals(mplsBos, that.mplsBos());
420 }
421 return false;
422 }
423 }
424
425 /**
Yuta HIGUCHIcca5e722015-02-05 14:00:41 -0800426 * Represents a MPLS TTL modification.
sangho3f97a17d2015-01-29 22:56:29 -0800427 */
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800428 public static final class ModMplsTtlInstruction
429 extends L2ModificationInstruction {
sangho3f97a17d2015-01-29 22:56:29 -0800430
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800431 ModMplsTtlInstruction() {
sangho3f97a17d2015-01-29 22:56:29 -0800432 }
433
434 @Override
435 public L2SubType subtype() {
436 return L2SubType.DEC_MPLS_TTL;
437 }
438
439 @Override
440 public String toString() {
Jonathan Hartc7840bd2016-01-21 23:26:29 -0800441 return subtype().toString();
sangho3f97a17d2015-01-29 22:56:29 -0800442 }
443
444 @Override
445 public int hashCode() {
Yuta HIGUCHIcca5e722015-02-05 14:00:41 -0800446 return Objects.hash(type(), subtype());
sangho3f97a17d2015-01-29 22:56:29 -0800447 }
448
449 @Override
450 public boolean equals(Object obj) {
451 if (this == obj) {
452 return true;
453 }
Yuta HIGUCHIcca5e722015-02-05 14:00:41 -0800454 if (obj instanceof ModMplsTtlInstruction) {
455 return true;
sangho3f97a17d2015-01-29 22:56:29 -0800456 }
457 return false;
458 }
459 }
Hyunsun Moona08c5d02015-07-14 17:53:00 -0700460
461 /**
462 * Represents a Tunnel id modification.
463 */
464 public static final class ModTunnelIdInstruction
465 extends L2ModificationInstruction {
466
467 private final long tunnelId;
468
469 ModTunnelIdInstruction(long tunnelId) {
470 this.tunnelId = tunnelId;
471 }
472
473 public long tunnelId() {
474 return this.tunnelId;
475 }
476
477 @Override
478 public L2SubType subtype() {
479 return L2SubType.TUNNEL_ID;
480 }
481
482 @Override
483 public String toString() {
Jonathan Hartc7840bd2016-01-21 23:26:29 -0800484 return subtype().toString() + SEPARATOR + Long.toHexString(tunnelId);
Hyunsun Moona08c5d02015-07-14 17:53:00 -0700485 }
486
487 @Override
488 public int hashCode() {
489 return Objects.hash(type(), subtype(), tunnelId);
490 }
491
492 @Override
493 public boolean equals(Object obj) {
494 if (this == obj) {
495 return true;
496 }
497 if (obj instanceof ModTunnelIdInstruction) {
498 ModTunnelIdInstruction that = (ModTunnelIdInstruction) obj;
499 return Objects.equals(tunnelId, that.tunnelId);
500 }
501 return false;
502 }
503 }
alshabib55a55d92014-09-16 11:59:31 -0700504}