blob: bfb63009780d2181db223cd0e187d6e975a5f81e [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 /**
87 * Tunnle id modification.
88 */
89 TUNNEL_ID
alshabib55a55d92014-09-16 11:59:31 -070090 }
91
92 // TODO: Create factory class 'Instructions' that will have various factory
93 // to create specific instructions.
94
alshabib35edb1a2014-09-16 17:44:44 -070095 public abstract L2SubType subtype();
alshabib55a55d92014-09-16 11:59:31 -070096
97 @Override
Yuta HIGUCHI6a479642015-02-08 01:28:50 -080098 public final Type type() {
alshabib35edb1a2014-09-16 17:44:44 -070099 return Type.L2MODIFICATION;
alshabib55a55d92014-09-16 11:59:31 -0700100 }
101
102 /**
103 * Represents a L2 src/dst modification instruction.
104 */
105 public static final class ModEtherInstruction extends L2ModificationInstruction {
106
alshabib35edb1a2014-09-16 17:44:44 -0700107 private final L2SubType subtype;
Ayaka Koshibea9c199f2014-09-16 16:21:40 -0700108 private final MacAddress mac;
alshabib55a55d92014-09-16 11:59:31 -0700109
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800110 ModEtherInstruction(L2SubType subType, MacAddress addr) {
alshabib64231f62014-09-16 17:58:36 -0700111
alshabib55a55d92014-09-16 11:59:31 -0700112 this.subtype = subType;
113 this.mac = addr;
114 }
115
116 @Override
alshabib35edb1a2014-09-16 17:44:44 -0700117 public L2SubType subtype() {
alshabib55a55d92014-09-16 11:59:31 -0700118 return this.subtype;
119 }
120
Ayaka Koshibea9c199f2014-09-16 16:21:40 -0700121 public MacAddress mac() {
alshabib55a55d92014-09-16 11:59:31 -0700122 return this.mac;
123 }
124
alshabib99b8fdc2014-09-25 14:30:22 -0700125 @Override
126 public String toString() {
127 return toStringHelper(subtype().toString())
128 .add("mac", mac).toString();
129 }
130
alshabib8ca53902014-10-07 13:11:17 -0700131 @Override
132 public int hashCode() {
Thomas Vachuska9b2da212014-11-10 19:30:25 -0800133 return Objects.hash(type(), subtype, mac);
alshabib8ca53902014-10-07 13:11:17 -0700134 }
135
136 @Override
137 public boolean equals(Object obj) {
138 if (this == obj) {
139 return true;
140 }
141 if (obj instanceof ModEtherInstruction) {
142 ModEtherInstruction that = (ModEtherInstruction) obj;
143 return Objects.equals(mac, that.mac) &&
144 Objects.equals(subtype, that.subtype);
alshabib8ca53902014-10-07 13:11:17 -0700145 }
146 return false;
147 }
alshabib55a55d92014-09-16 11:59:31 -0700148 }
149
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800150 // TODO This instruction is reused for Pop-Mpls. Consider renaming.
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800151 public static final class PushHeaderInstructions extends
152 L2ModificationInstruction {
153
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800154
alshabib7b808c52015-06-26 14:22:24 -0700155 private final L2SubType subtype;
156 private final EthType ethernetType; // Ethernet type value: 16 bits
157
158 PushHeaderInstructions(L2SubType subType, EthType ethernetType) {
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800159 this.subtype = subType;
alshabib7b808c52015-06-26 14:22:24 -0700160 this.ethernetType = ethernetType;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800161 }
162
alshabib7b808c52015-06-26 14:22:24 -0700163 public EthType ethernetType() {
alshabib0ad43982015-05-07 13:43:13 -0700164 return ethernetType;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800165 }
166
167 @Override
168 public L2SubType subtype() {
169 return this.subtype;
170 }
171
172 @Override
173 public String toString() {
Yuta HIGUCHI32a53c52015-02-08 01:25:40 -0800174 return toStringHelper(subtype().toString())
alshabib7b808c52015-06-26 14:22:24 -0700175 .add("ethernetType", ethernetType())
Yuta HIGUCHI32a53c52015-02-08 01:25:40 -0800176 .toString();
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800177 }
178
179 @Override
180 public int hashCode() {
Yuta HIGUCHI32a53c52015-02-08 01:25:40 -0800181 return Objects.hash(type(), subtype, ethernetType);
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800182 }
183
184 @Override
185 public boolean equals(Object obj) {
186 if (this == obj) {
187 return true;
188 }
189 if (obj instanceof PushHeaderInstructions) {
190 PushHeaderInstructions that = (PushHeaderInstructions) obj;
Yuta HIGUCHI32a53c52015-02-08 01:25:40 -0800191 return Objects.equals(subtype, that.subtype) &&
192 Objects.equals(this.ethernetType, that.ethernetType);
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800193 }
194 return false;
195 }
196 }
197
198
199
alshabib55a55d92014-09-16 11:59:31 -0700200 /**
alshabib55a55d92014-09-16 11:59:31 -0700201 * Represents a VLAN id modification instruction.
202 */
203 public static final class ModVlanIdInstruction extends L2ModificationInstruction {
204
Ray Milkey78081052014-11-05 10:38:12 -0800205 private final VlanId vlanId;
alshabib55a55d92014-09-16 11:59:31 -0700206
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800207 ModVlanIdInstruction(VlanId vlanId) {
alshabib55a55d92014-09-16 11:59:31 -0700208 this.vlanId = vlanId;
209 }
210
211 @Override
alshabib35edb1a2014-09-16 17:44:44 -0700212 public L2SubType subtype() {
alshabib7410fea2014-09-16 13:48:39 -0700213 return L2SubType.VLAN_ID;
alshabib55a55d92014-09-16 11:59:31 -0700214 }
215
Ayaka Koshibea9c199f2014-09-16 16:21:40 -0700216 public VlanId vlanId() {
alshabib55a55d92014-09-16 11:59:31 -0700217 return this.vlanId;
218 }
219
alshabib99b8fdc2014-09-25 14:30:22 -0700220 @Override
221 public String toString() {
222 return toStringHelper(subtype().toString())
223 .add("id", vlanId).toString();
224 }
225
alshabib8ca53902014-10-07 13:11:17 -0700226 @Override
227 public int hashCode() {
Thomas Vachuska9b2da212014-11-10 19:30:25 -0800228 return Objects.hash(type(), subtype(), vlanId);
alshabib8ca53902014-10-07 13:11:17 -0700229 }
230
231 @Override
232 public boolean equals(Object obj) {
233 if (this == obj) {
234 return true;
235 }
236 if (obj instanceof ModVlanIdInstruction) {
237 ModVlanIdInstruction that = (ModVlanIdInstruction) obj;
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800238 return Objects.equals(vlanId, that.vlanId);
alshabib8ca53902014-10-07 13:11:17 -0700239 }
240 return false;
241 }
alshabib55a55d92014-09-16 11:59:31 -0700242 }
243
alshabib7410fea2014-09-16 13:48:39 -0700244 /**
245 * Represents a VLAN PCP modification instruction.
246 */
247 public static final class ModVlanPcpInstruction extends L2ModificationInstruction {
248
alshabib0ad43982015-05-07 13:43:13 -0700249 private static final byte MASK = 0x7;
250 private final byte vlanPcp;
alshabib7410fea2014-09-16 13:48:39 -0700251
alshabib0ad43982015-05-07 13:43:13 -0700252 ModVlanPcpInstruction(byte vlanPcp) {
253 this.vlanPcp = (byte) (vlanPcp & MASK);
alshabib7410fea2014-09-16 13:48:39 -0700254 }
255
256 @Override
alshabib35edb1a2014-09-16 17:44:44 -0700257 public L2SubType subtype() {
alshabib7410fea2014-09-16 13:48:39 -0700258 return L2SubType.VLAN_PCP;
259 }
260
alshabib0ad43982015-05-07 13:43:13 -0700261 public byte vlanPcp() {
alshabib7410fea2014-09-16 13:48:39 -0700262 return this.vlanPcp;
263 }
264
alshabib99b8fdc2014-09-25 14:30:22 -0700265 @Override
266 public String toString() {
267 return toStringHelper(subtype().toString())
268 .add("pcp", Long.toHexString(vlanPcp)).toString();
269 }
270
alshabib8ca53902014-10-07 13:11:17 -0700271 @Override
272 public int hashCode() {
Thomas Vachuska9b2da212014-11-10 19:30:25 -0800273 return Objects.hash(type(), subtype(), vlanPcp);
alshabib8ca53902014-10-07 13:11:17 -0700274 }
275
276 @Override
277 public boolean equals(Object obj) {
278 if (this == obj) {
279 return true;
280 }
281 if (obj instanceof ModVlanPcpInstruction) {
282 ModVlanPcpInstruction that = (ModVlanPcpInstruction) obj;
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800283 return Objects.equals(vlanPcp, that.vlanPcp);
alshabib8ca53902014-10-07 13:11:17 -0700284 }
285 return false;
286 }
alshabib7410fea2014-09-16 13:48:39 -0700287 }
288
Saurav Dasfbe25c52015-03-04 11:12:00 -0800289 /**
290 * Represents a VLAN POP modification instruction.
291 */
292 public static final class PopVlanInstruction extends L2ModificationInstruction {
293 private final L2SubType subtype;
294
295 PopVlanInstruction(L2SubType subType) {
296 this.subtype = subType;
297 }
298
299 @Override
300 public L2SubType subtype() {
301 return subtype;
302 }
303
304 @Override
305 public String toString() {
306 return toStringHelper(subtype().toString())
307 .toString();
308 }
309
310 @Override
311 public int hashCode() {
312 return Objects.hash(type(), subtype);
313 }
314
315 @Override
316 public boolean equals(Object obj) {
317 if (this == obj) {
318 return true;
319 }
HIGUCHI Yuta7bb8b3f2015-03-13 23:21:37 -0700320 if (obj instanceof PopVlanInstruction) {
321 PopVlanInstruction that = (PopVlanInstruction) obj;
Saurav Dasfbe25c52015-03-04 11:12:00 -0800322 return Objects.equals(subtype, that.subtype);
323 }
324 return false;
325 }
326 }
alshabib55a55d92014-09-16 11:59:31 -0700327
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800328 /**
329 * Represents a MPLS label modification.
330 */
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800331 public static final class ModMplsLabelInstruction
332 extends L2ModificationInstruction {
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800333
Michele Santuari4b6019e2014-12-19 11:31:45 +0100334 private final MplsLabel mplsLabel;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800335
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800336 ModMplsLabelInstruction(MplsLabel mplsLabel) {
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800337 this.mplsLabel = mplsLabel;
338 }
339
340 public Integer label() {
Michele Santuari4b6019e2014-12-19 11:31:45 +0100341 return mplsLabel.toInt();
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800342 }
343
344 @Override
345 public L2SubType subtype() {
346 return L2SubType.MPLS_LABEL;
347 }
348
349 @Override
350 public String toString() {
Pavlin Radoslavov3ebe1702015-02-17 09:53:17 -0800351 return toStringHelper(subtype().toString())
Michele Santuari4b6019e2014-12-19 11:31:45 +0100352 .add("mpls", mplsLabel).toString();
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800353 }
354
355 @Override
356 public int hashCode() {
Yuta HIGUCHIcca5e722015-02-05 14:00:41 -0800357 return Objects.hash(type(), subtype(), mplsLabel);
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800358 }
359
360 @Override
361 public boolean equals(Object obj) {
362 if (this == obj) {
363 return true;
364 }
365 if (obj instanceof ModMplsLabelInstruction) {
366 ModMplsLabelInstruction that = (ModMplsLabelInstruction) obj;
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800367 return Objects.equals(mplsLabel, that.mplsLabel);
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800368 }
369 return false;
370 }
371 }
sangho3f97a17d2015-01-29 22:56:29 -0800372
373 /**
Yuta HIGUCHIcca5e722015-02-05 14:00:41 -0800374 * Represents a MPLS TTL modification.
sangho3f97a17d2015-01-29 22:56:29 -0800375 */
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800376 public static final class ModMplsTtlInstruction
377 extends L2ModificationInstruction {
sangho3f97a17d2015-01-29 22:56:29 -0800378
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800379 ModMplsTtlInstruction() {
sangho3f97a17d2015-01-29 22:56:29 -0800380 }
381
382 @Override
383 public L2SubType subtype() {
384 return L2SubType.DEC_MPLS_TTL;
385 }
386
387 @Override
388 public String toString() {
Yuta HIGUCHIcca5e722015-02-05 14:00:41 -0800389 return toStringHelper(subtype().toString())
390 .toString();
sangho3f97a17d2015-01-29 22:56:29 -0800391 }
392
393 @Override
394 public int hashCode() {
Yuta HIGUCHIcca5e722015-02-05 14:00:41 -0800395 return Objects.hash(type(), subtype());
sangho3f97a17d2015-01-29 22:56:29 -0800396 }
397
398 @Override
399 public boolean equals(Object obj) {
400 if (this == obj) {
401 return true;
402 }
Yuta HIGUCHIcca5e722015-02-05 14:00:41 -0800403 if (obj instanceof ModMplsTtlInstruction) {
404 return true;
sangho3f97a17d2015-01-29 22:56:29 -0800405 }
406 return false;
407 }
408 }
Hyunsun Moona08c5d02015-07-14 17:53:00 -0700409
410 /**
411 * Represents a Tunnel id modification.
412 */
413 public static final class ModTunnelIdInstruction
414 extends L2ModificationInstruction {
415
416 private final long tunnelId;
417
418 ModTunnelIdInstruction(long tunnelId) {
419 this.tunnelId = tunnelId;
420 }
421
422 public long tunnelId() {
423 return this.tunnelId;
424 }
425
426 @Override
427 public L2SubType subtype() {
428 return L2SubType.TUNNEL_ID;
429 }
430
431 @Override
432 public String toString() {
433 return toStringHelper(subtype().toString())
434 .add("id", Long.toHexString(tunnelId))
435 .toString();
436 }
437
438 @Override
439 public int hashCode() {
440 return Objects.hash(type(), subtype(), tunnelId);
441 }
442
443 @Override
444 public boolean equals(Object obj) {
445 if (this == obj) {
446 return true;
447 }
448 if (obj instanceof ModTunnelIdInstruction) {
449 ModTunnelIdInstruction that = (ModTunnelIdInstruction) obj;
450 return Objects.equals(tunnelId, that.tunnelId);
451 }
452 return false;
453 }
454 }
alshabib55a55d92014-09-16 11:59:31 -0700455}