blob: 2fd809fcff60b54321997ccea3d823daf5624b6d [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 */
84 VLAN_PUSH
alshabib55a55d92014-09-16 11:59:31 -070085 }
86
87 // TODO: Create factory class 'Instructions' that will have various factory
88 // to create specific instructions.
89
alshabib35edb1a2014-09-16 17:44:44 -070090 public abstract L2SubType subtype();
alshabib55a55d92014-09-16 11:59:31 -070091
92 @Override
Yuta HIGUCHI6a479642015-02-08 01:28:50 -080093 public final Type type() {
alshabib35edb1a2014-09-16 17:44:44 -070094 return Type.L2MODIFICATION;
alshabib55a55d92014-09-16 11:59:31 -070095 }
96
97 /**
98 * Represents a L2 src/dst modification instruction.
99 */
100 public static final class ModEtherInstruction extends L2ModificationInstruction {
101
alshabib35edb1a2014-09-16 17:44:44 -0700102 private final L2SubType subtype;
Ayaka Koshibea9c199f2014-09-16 16:21:40 -0700103 private final MacAddress mac;
alshabib55a55d92014-09-16 11:59:31 -0700104
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800105 ModEtherInstruction(L2SubType subType, MacAddress addr) {
alshabib64231f62014-09-16 17:58:36 -0700106
alshabib55a55d92014-09-16 11:59:31 -0700107 this.subtype = subType;
108 this.mac = addr;
109 }
110
111 @Override
alshabib35edb1a2014-09-16 17:44:44 -0700112 public L2SubType subtype() {
alshabib55a55d92014-09-16 11:59:31 -0700113 return this.subtype;
114 }
115
Ayaka Koshibea9c199f2014-09-16 16:21:40 -0700116 public MacAddress mac() {
alshabib55a55d92014-09-16 11:59:31 -0700117 return this.mac;
118 }
119
alshabib99b8fdc2014-09-25 14:30:22 -0700120 @Override
121 public String toString() {
122 return toStringHelper(subtype().toString())
123 .add("mac", mac).toString();
124 }
125
alshabib8ca53902014-10-07 13:11:17 -0700126 @Override
127 public int hashCode() {
Thomas Vachuska9b2da212014-11-10 19:30:25 -0800128 return Objects.hash(type(), subtype, mac);
alshabib8ca53902014-10-07 13:11:17 -0700129 }
130
131 @Override
132 public boolean equals(Object obj) {
133 if (this == obj) {
134 return true;
135 }
136 if (obj instanceof ModEtherInstruction) {
137 ModEtherInstruction that = (ModEtherInstruction) obj;
138 return Objects.equals(mac, that.mac) &&
139 Objects.equals(subtype, that.subtype);
alshabib8ca53902014-10-07 13:11:17 -0700140 }
141 return false;
142 }
alshabib55a55d92014-09-16 11:59:31 -0700143 }
144
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800145 // TODO This instruction is reused for Pop-Mpls. Consider renaming.
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800146 public static final class PushHeaderInstructions extends
147 L2ModificationInstruction {
148
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800149
alshabib7b808c52015-06-26 14:22:24 -0700150 private final L2SubType subtype;
151 private final EthType ethernetType; // Ethernet type value: 16 bits
152
153 PushHeaderInstructions(L2SubType subType, EthType ethernetType) {
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800154 this.subtype = subType;
alshabib7b808c52015-06-26 14:22:24 -0700155 this.ethernetType = ethernetType;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800156 }
157
alshabib7b808c52015-06-26 14:22:24 -0700158 public EthType ethernetType() {
alshabib0ad43982015-05-07 13:43:13 -0700159 return ethernetType;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800160 }
161
162 @Override
163 public L2SubType subtype() {
164 return this.subtype;
165 }
166
167 @Override
168 public String toString() {
Yuta HIGUCHI32a53c52015-02-08 01:25:40 -0800169 return toStringHelper(subtype().toString())
alshabib7b808c52015-06-26 14:22:24 -0700170 .add("ethernetType", ethernetType())
Yuta HIGUCHI32a53c52015-02-08 01:25:40 -0800171 .toString();
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800172 }
173
174 @Override
175 public int hashCode() {
Yuta HIGUCHI32a53c52015-02-08 01:25:40 -0800176 return Objects.hash(type(), subtype, ethernetType);
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800177 }
178
179 @Override
180 public boolean equals(Object obj) {
181 if (this == obj) {
182 return true;
183 }
184 if (obj instanceof PushHeaderInstructions) {
185 PushHeaderInstructions that = (PushHeaderInstructions) obj;
Yuta HIGUCHI32a53c52015-02-08 01:25:40 -0800186 return Objects.equals(subtype, that.subtype) &&
187 Objects.equals(this.ethernetType, that.ethernetType);
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800188 }
189 return false;
190 }
191 }
192
193
194
alshabib55a55d92014-09-16 11:59:31 -0700195 /**
alshabib55a55d92014-09-16 11:59:31 -0700196 * Represents a VLAN id modification instruction.
197 */
198 public static final class ModVlanIdInstruction extends L2ModificationInstruction {
199
Ray Milkey78081052014-11-05 10:38:12 -0800200 private final VlanId vlanId;
alshabib55a55d92014-09-16 11:59:31 -0700201
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800202 ModVlanIdInstruction(VlanId vlanId) {
alshabib55a55d92014-09-16 11:59:31 -0700203 this.vlanId = vlanId;
204 }
205
206 @Override
alshabib35edb1a2014-09-16 17:44:44 -0700207 public L2SubType subtype() {
alshabib7410fea2014-09-16 13:48:39 -0700208 return L2SubType.VLAN_ID;
alshabib55a55d92014-09-16 11:59:31 -0700209 }
210
Ayaka Koshibea9c199f2014-09-16 16:21:40 -0700211 public VlanId vlanId() {
alshabib55a55d92014-09-16 11:59:31 -0700212 return this.vlanId;
213 }
214
alshabib99b8fdc2014-09-25 14:30:22 -0700215 @Override
216 public String toString() {
217 return toStringHelper(subtype().toString())
218 .add("id", vlanId).toString();
219 }
220
alshabib8ca53902014-10-07 13:11:17 -0700221 @Override
222 public int hashCode() {
Thomas Vachuska9b2da212014-11-10 19:30:25 -0800223 return Objects.hash(type(), subtype(), vlanId);
alshabib8ca53902014-10-07 13:11:17 -0700224 }
225
226 @Override
227 public boolean equals(Object obj) {
228 if (this == obj) {
229 return true;
230 }
231 if (obj instanceof ModVlanIdInstruction) {
232 ModVlanIdInstruction that = (ModVlanIdInstruction) obj;
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800233 return Objects.equals(vlanId, that.vlanId);
alshabib8ca53902014-10-07 13:11:17 -0700234 }
235 return false;
236 }
alshabib55a55d92014-09-16 11:59:31 -0700237 }
238
alshabib7410fea2014-09-16 13:48:39 -0700239 /**
240 * Represents a VLAN PCP modification instruction.
241 */
242 public static final class ModVlanPcpInstruction extends L2ModificationInstruction {
243
alshabib0ad43982015-05-07 13:43:13 -0700244 private static final byte MASK = 0x7;
245 private final byte vlanPcp;
alshabib7410fea2014-09-16 13:48:39 -0700246
alshabib0ad43982015-05-07 13:43:13 -0700247 ModVlanPcpInstruction(byte vlanPcp) {
248 this.vlanPcp = (byte) (vlanPcp & MASK);
alshabib7410fea2014-09-16 13:48:39 -0700249 }
250
251 @Override
alshabib35edb1a2014-09-16 17:44:44 -0700252 public L2SubType subtype() {
alshabib7410fea2014-09-16 13:48:39 -0700253 return L2SubType.VLAN_PCP;
254 }
255
alshabib0ad43982015-05-07 13:43:13 -0700256 public byte vlanPcp() {
alshabib7410fea2014-09-16 13:48:39 -0700257 return this.vlanPcp;
258 }
259
alshabib99b8fdc2014-09-25 14:30:22 -0700260 @Override
261 public String toString() {
262 return toStringHelper(subtype().toString())
263 .add("pcp", Long.toHexString(vlanPcp)).toString();
264 }
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 /**
285 * Represents a VLAN POP modification instruction.
286 */
287 public static final class PopVlanInstruction extends L2ModificationInstruction {
288 private final L2SubType subtype;
289
290 PopVlanInstruction(L2SubType subType) {
291 this.subtype = subType;
292 }
293
294 @Override
295 public L2SubType subtype() {
296 return subtype;
297 }
298
299 @Override
300 public String toString() {
301 return toStringHelper(subtype().toString())
302 .toString();
303 }
304
305 @Override
306 public int hashCode() {
307 return Objects.hash(type(), subtype);
308 }
309
310 @Override
311 public boolean equals(Object obj) {
312 if (this == obj) {
313 return true;
314 }
HIGUCHI Yuta7bb8b3f2015-03-13 23:21:37 -0700315 if (obj instanceof PopVlanInstruction) {
316 PopVlanInstruction that = (PopVlanInstruction) obj;
Saurav Dasfbe25c52015-03-04 11:12:00 -0800317 return Objects.equals(subtype, that.subtype);
318 }
319 return false;
320 }
321 }
alshabib55a55d92014-09-16 11:59:31 -0700322
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800323 /**
324 * Represents a MPLS label modification.
325 */
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800326 public static final class ModMplsLabelInstruction
327 extends L2ModificationInstruction {
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800328
Michele Santuari4b6019e2014-12-19 11:31:45 +0100329 private final MplsLabel mplsLabel;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800330
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800331 ModMplsLabelInstruction(MplsLabel mplsLabel) {
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800332 this.mplsLabel = mplsLabel;
333 }
334
335 public Integer label() {
Michele Santuari4b6019e2014-12-19 11:31:45 +0100336 return mplsLabel.toInt();
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800337 }
338
339 @Override
340 public L2SubType subtype() {
341 return L2SubType.MPLS_LABEL;
342 }
343
344 @Override
345 public String toString() {
Pavlin Radoslavov3ebe1702015-02-17 09:53:17 -0800346 return toStringHelper(subtype().toString())
Michele Santuari4b6019e2014-12-19 11:31:45 +0100347 .add("mpls", mplsLabel).toString();
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800348 }
349
350 @Override
351 public int hashCode() {
Yuta HIGUCHIcca5e722015-02-05 14:00:41 -0800352 return Objects.hash(type(), subtype(), mplsLabel);
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800353 }
354
355 @Override
356 public boolean equals(Object obj) {
357 if (this == obj) {
358 return true;
359 }
360 if (obj instanceof ModMplsLabelInstruction) {
361 ModMplsLabelInstruction that = (ModMplsLabelInstruction) obj;
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800362 return Objects.equals(mplsLabel, that.mplsLabel);
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800363 }
364 return false;
365 }
366 }
sangho3f97a17d2015-01-29 22:56:29 -0800367
368 /**
Yuta HIGUCHIcca5e722015-02-05 14:00:41 -0800369 * Represents a MPLS TTL modification.
sangho3f97a17d2015-01-29 22:56:29 -0800370 */
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800371 public static final class ModMplsTtlInstruction
372 extends L2ModificationInstruction {
sangho3f97a17d2015-01-29 22:56:29 -0800373
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800374 ModMplsTtlInstruction() {
sangho3f97a17d2015-01-29 22:56:29 -0800375 }
376
377 @Override
378 public L2SubType subtype() {
379 return L2SubType.DEC_MPLS_TTL;
380 }
381
382 @Override
383 public String toString() {
Yuta HIGUCHIcca5e722015-02-05 14:00:41 -0800384 return toStringHelper(subtype().toString())
385 .toString();
sangho3f97a17d2015-01-29 22:56:29 -0800386 }
387
388 @Override
389 public int hashCode() {
Yuta HIGUCHIcca5e722015-02-05 14:00:41 -0800390 return Objects.hash(type(), subtype());
sangho3f97a17d2015-01-29 22:56:29 -0800391 }
392
393 @Override
394 public boolean equals(Object obj) {
395 if (this == obj) {
396 return true;
397 }
Yuta HIGUCHIcca5e722015-02-05 14:00:41 -0800398 if (obj instanceof ModMplsTtlInstruction) {
399 return true;
sangho3f97a17d2015-01-29 22:56:29 -0800400 }
401 return false;
402 }
403 }
alshabib55a55d92014-09-16 11:59:31 -0700404}