blob: b993848991625aa2bce308e43499d077485a0cb4 [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
Ayaka Koshibea9c199f2014-09-16 16:21:40 -070018import org.onlab.packet.MacAddress;
Michele Santuari4b6019e2014-12-19 11:31:45 +010019import org.onlab.packet.MplsLabel;
Ayaka Koshibea9c199f2014-09-16 16:21:40 -070020import org.onlab.packet.VlanId;
alshabib55a55d92014-09-16 11:59:31 -070021
Jonathan Hart54b406b2015-03-06 16:24:14 -080022import java.util.Objects;
23
24import static com.google.common.base.MoreObjects.toStringHelper;
25
alshabib55a55d92014-09-16 11:59:31 -070026/**
27 * Abstraction of a single traffic treatment step.
alshabib55a55d92014-09-16 11:59:31 -070028 */
29public abstract class L2ModificationInstruction implements Instruction {
30
31 /**
32 * Represents the type of traffic treatment.
33 */
alshabib35edb1a2014-09-16 17:44:44 -070034 public enum L2SubType {
alshabib55a55d92014-09-16 11:59:31 -070035 /**
36 * Ether src modification.
37 */
alshabib99b8fdc2014-09-25 14:30:22 -070038 ETH_SRC,
alshabib55a55d92014-09-16 11:59:31 -070039
40 /**
41 * Ether dst modification.
42 */
alshabib99b8fdc2014-09-25 14:30:22 -070043 ETH_DST,
alshabib55a55d92014-09-16 11:59:31 -070044
45 /**
alshabib55a55d92014-09-16 11:59:31 -070046 * VLAN id modification.
47 */
48 VLAN_ID,
49
50 /**
51 * VLAN priority modification.
52 */
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -080053 VLAN_PCP,
54
55 /**
56 * MPLS Label modification.
57 */
58 MPLS_LABEL,
59
60 /**
61 * MPLS Push modification.
62 */
63 MPLS_PUSH,
64
65 /**
66 * MPLS Pop modification.
67 */
sangho3f97a17d2015-01-29 22:56:29 -080068 MPLS_POP,
69
70 /**
71 * MPLS TTL modification.
72 */
Saurav Dasfbe25c52015-03-04 11:12:00 -080073 DEC_MPLS_TTL,
sangho3f97a17d2015-01-29 22:56:29 -080074
Saurav Dasfbe25c52015-03-04 11:12:00 -080075 /**
76 * VLAN Pop modification.
77 */
Jonathan Hart54b406b2015-03-06 16:24:14 -080078 VLAN_POP,
79
80 /**
81 * VLAN Push modification.
82 */
83 VLAN_PUSH
alshabib55a55d92014-09-16 11:59:31 -070084 }
85
86 // TODO: Create factory class 'Instructions' that will have various factory
87 // to create specific instructions.
88
alshabib35edb1a2014-09-16 17:44:44 -070089 public abstract L2SubType subtype();
alshabib55a55d92014-09-16 11:59:31 -070090
91 @Override
Yuta HIGUCHI6a479642015-02-08 01:28:50 -080092 public final Type type() {
alshabib35edb1a2014-09-16 17:44:44 -070093 return Type.L2MODIFICATION;
alshabib55a55d92014-09-16 11:59:31 -070094 }
95
96 /**
97 * Represents a L2 src/dst modification instruction.
98 */
99 public static final class ModEtherInstruction extends L2ModificationInstruction {
100
alshabib35edb1a2014-09-16 17:44:44 -0700101 private final L2SubType subtype;
Ayaka Koshibea9c199f2014-09-16 16:21:40 -0700102 private final MacAddress mac;
alshabib55a55d92014-09-16 11:59:31 -0700103
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800104 ModEtherInstruction(L2SubType subType, MacAddress addr) {
alshabib64231f62014-09-16 17:58:36 -0700105
alshabib55a55d92014-09-16 11:59:31 -0700106 this.subtype = subType;
107 this.mac = addr;
108 }
109
110 @Override
alshabib35edb1a2014-09-16 17:44:44 -0700111 public L2SubType subtype() {
alshabib55a55d92014-09-16 11:59:31 -0700112 return this.subtype;
113 }
114
Ayaka Koshibea9c199f2014-09-16 16:21:40 -0700115 public MacAddress mac() {
alshabib55a55d92014-09-16 11:59:31 -0700116 return this.mac;
117 }
118
alshabib99b8fdc2014-09-25 14:30:22 -0700119 @Override
120 public String toString() {
121 return toStringHelper(subtype().toString())
122 .add("mac", mac).toString();
123 }
124
alshabib8ca53902014-10-07 13:11:17 -0700125 @Override
126 public int hashCode() {
Thomas Vachuska9b2da212014-11-10 19:30:25 -0800127 return Objects.hash(type(), subtype, mac);
alshabib8ca53902014-10-07 13:11:17 -0700128 }
129
130 @Override
131 public boolean equals(Object obj) {
132 if (this == obj) {
133 return true;
134 }
135 if (obj instanceof ModEtherInstruction) {
136 ModEtherInstruction that = (ModEtherInstruction) obj;
137 return Objects.equals(mac, that.mac) &&
138 Objects.equals(subtype, that.subtype);
alshabib8ca53902014-10-07 13:11:17 -0700139 }
140 return false;
141 }
alshabib55a55d92014-09-16 11:59:31 -0700142 }
143
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800144 // TODO This instruction is reused for Pop-Mpls. Consider renaming.
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800145 public static final class PushHeaderInstructions extends
146 L2ModificationInstruction {
147
alshabib0ad43982015-05-07 13:43:13 -0700148 private static final int MASK = 0xffff;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800149 private final L2SubType subtype;
alshabib0ad43982015-05-07 13:43:13 -0700150 private final int ethernetType; // Ethernet type value: 16 bits
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800151
alshabib0ad43982015-05-07 13:43:13 -0700152 PushHeaderInstructions(L2SubType subType, int ethernetType) {
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800153 this.subtype = subType;
alshabib0ad43982015-05-07 13:43:13 -0700154 this.ethernetType = ethernetType & MASK;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800155 }
156
Yuta HIGUCHI32a53c52015-02-08 01:25:40 -0800157 public int ethernetType() {
alshabib0ad43982015-05-07 13:43:13 -0700158 return ethernetType;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800159 }
160
161 @Override
162 public L2SubType subtype() {
163 return this.subtype;
164 }
165
166 @Override
167 public String toString() {
Yuta HIGUCHI32a53c52015-02-08 01:25:40 -0800168 return toStringHelper(subtype().toString())
169 .add("ethernetType", String.format("0x%04x", ethernetType()))
170 .toString();
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800171 }
172
173 @Override
174 public int hashCode() {
Yuta HIGUCHI32a53c52015-02-08 01:25:40 -0800175 return Objects.hash(type(), subtype, ethernetType);
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800176 }
177
178 @Override
179 public boolean equals(Object obj) {
180 if (this == obj) {
181 return true;
182 }
183 if (obj instanceof PushHeaderInstructions) {
184 PushHeaderInstructions that = (PushHeaderInstructions) obj;
Yuta HIGUCHI32a53c52015-02-08 01:25:40 -0800185 return Objects.equals(subtype, that.subtype) &&
186 Objects.equals(this.ethernetType, that.ethernetType);
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800187 }
188 return false;
189 }
190 }
191
192
193
alshabib55a55d92014-09-16 11:59:31 -0700194 /**
alshabib55a55d92014-09-16 11:59:31 -0700195 * Represents a VLAN id modification instruction.
196 */
197 public static final class ModVlanIdInstruction extends L2ModificationInstruction {
198
Ray Milkey78081052014-11-05 10:38:12 -0800199 private final VlanId vlanId;
alshabib55a55d92014-09-16 11:59:31 -0700200
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800201 ModVlanIdInstruction(VlanId vlanId) {
alshabib55a55d92014-09-16 11:59:31 -0700202 this.vlanId = vlanId;
203 }
204
205 @Override
alshabib35edb1a2014-09-16 17:44:44 -0700206 public L2SubType subtype() {
alshabib7410fea2014-09-16 13:48:39 -0700207 return L2SubType.VLAN_ID;
alshabib55a55d92014-09-16 11:59:31 -0700208 }
209
Ayaka Koshibea9c199f2014-09-16 16:21:40 -0700210 public VlanId vlanId() {
alshabib55a55d92014-09-16 11:59:31 -0700211 return this.vlanId;
212 }
213
alshabib99b8fdc2014-09-25 14:30:22 -0700214 @Override
215 public String toString() {
216 return toStringHelper(subtype().toString())
217 .add("id", vlanId).toString();
218 }
219
alshabib8ca53902014-10-07 13:11:17 -0700220 @Override
221 public int hashCode() {
Thomas Vachuska9b2da212014-11-10 19:30:25 -0800222 return Objects.hash(type(), subtype(), vlanId);
alshabib8ca53902014-10-07 13:11:17 -0700223 }
224
225 @Override
226 public boolean equals(Object obj) {
227 if (this == obj) {
228 return true;
229 }
230 if (obj instanceof ModVlanIdInstruction) {
231 ModVlanIdInstruction that = (ModVlanIdInstruction) obj;
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800232 return Objects.equals(vlanId, that.vlanId);
alshabib8ca53902014-10-07 13:11:17 -0700233 }
234 return false;
235 }
alshabib55a55d92014-09-16 11:59:31 -0700236 }
237
alshabib7410fea2014-09-16 13:48:39 -0700238 /**
239 * Represents a VLAN PCP modification instruction.
240 */
241 public static final class ModVlanPcpInstruction extends L2ModificationInstruction {
242
alshabib0ad43982015-05-07 13:43:13 -0700243 private static final byte MASK = 0x7;
244 private final byte vlanPcp;
alshabib7410fea2014-09-16 13:48:39 -0700245
alshabib0ad43982015-05-07 13:43:13 -0700246 ModVlanPcpInstruction(byte vlanPcp) {
247 this.vlanPcp = (byte) (vlanPcp & MASK);
alshabib7410fea2014-09-16 13:48:39 -0700248 }
249
250 @Override
alshabib35edb1a2014-09-16 17:44:44 -0700251 public L2SubType subtype() {
alshabib7410fea2014-09-16 13:48:39 -0700252 return L2SubType.VLAN_PCP;
253 }
254
alshabib0ad43982015-05-07 13:43:13 -0700255 public byte vlanPcp() {
alshabib7410fea2014-09-16 13:48:39 -0700256 return this.vlanPcp;
257 }
258
alshabib99b8fdc2014-09-25 14:30:22 -0700259 @Override
260 public String toString() {
261 return toStringHelper(subtype().toString())
262 .add("pcp", Long.toHexString(vlanPcp)).toString();
263 }
264
alshabib8ca53902014-10-07 13:11:17 -0700265 @Override
266 public int hashCode() {
Thomas Vachuska9b2da212014-11-10 19:30:25 -0800267 return Objects.hash(type(), subtype(), vlanPcp);
alshabib8ca53902014-10-07 13:11:17 -0700268 }
269
270 @Override
271 public boolean equals(Object obj) {
272 if (this == obj) {
273 return true;
274 }
275 if (obj instanceof ModVlanPcpInstruction) {
276 ModVlanPcpInstruction that = (ModVlanPcpInstruction) obj;
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800277 return Objects.equals(vlanPcp, that.vlanPcp);
alshabib8ca53902014-10-07 13:11:17 -0700278 }
279 return false;
280 }
alshabib7410fea2014-09-16 13:48:39 -0700281 }
282
Saurav Dasfbe25c52015-03-04 11:12:00 -0800283 /**
284 * Represents a VLAN POP modification instruction.
285 */
286 public static final class PopVlanInstruction extends L2ModificationInstruction {
287 private final L2SubType subtype;
288
289 PopVlanInstruction(L2SubType subType) {
290 this.subtype = subType;
291 }
292
293 @Override
294 public L2SubType subtype() {
295 return subtype;
296 }
297
298 @Override
299 public String toString() {
300 return toStringHelper(subtype().toString())
301 .toString();
302 }
303
304 @Override
305 public int hashCode() {
306 return Objects.hash(type(), subtype);
307 }
308
309 @Override
310 public boolean equals(Object obj) {
311 if (this == obj) {
312 return true;
313 }
HIGUCHI Yuta7bb8b3f2015-03-13 23:21:37 -0700314 if (obj instanceof PopVlanInstruction) {
315 PopVlanInstruction that = (PopVlanInstruction) obj;
Saurav Dasfbe25c52015-03-04 11:12:00 -0800316 return Objects.equals(subtype, that.subtype);
317 }
318 return false;
319 }
320 }
alshabib55a55d92014-09-16 11:59:31 -0700321
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800322 /**
323 * Represents a MPLS label modification.
324 */
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800325 public static final class ModMplsLabelInstruction
326 extends L2ModificationInstruction {
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800327
Michele Santuari4b6019e2014-12-19 11:31:45 +0100328 private final MplsLabel mplsLabel;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800329
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800330 ModMplsLabelInstruction(MplsLabel mplsLabel) {
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800331 this.mplsLabel = mplsLabel;
332 }
333
334 public Integer label() {
Michele Santuari4b6019e2014-12-19 11:31:45 +0100335 return mplsLabel.toInt();
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800336 }
337
338 @Override
339 public L2SubType subtype() {
340 return L2SubType.MPLS_LABEL;
341 }
342
343 @Override
344 public String toString() {
Pavlin Radoslavov3ebe1702015-02-17 09:53:17 -0800345 return toStringHelper(subtype().toString())
Michele Santuari4b6019e2014-12-19 11:31:45 +0100346 .add("mpls", mplsLabel).toString();
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800347 }
348
349 @Override
350 public int hashCode() {
Yuta HIGUCHIcca5e722015-02-05 14:00:41 -0800351 return Objects.hash(type(), subtype(), mplsLabel);
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800352 }
353
354 @Override
355 public boolean equals(Object obj) {
356 if (this == obj) {
357 return true;
358 }
359 if (obj instanceof ModMplsLabelInstruction) {
360 ModMplsLabelInstruction that = (ModMplsLabelInstruction) obj;
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800361 return Objects.equals(mplsLabel, that.mplsLabel);
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800362 }
363 return false;
364 }
365 }
sangho3f97a17d2015-01-29 22:56:29 -0800366
367 /**
Yuta HIGUCHIcca5e722015-02-05 14:00:41 -0800368 * Represents a MPLS TTL modification.
sangho3f97a17d2015-01-29 22:56:29 -0800369 */
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800370 public static final class ModMplsTtlInstruction
371 extends L2ModificationInstruction {
sangho3f97a17d2015-01-29 22:56:29 -0800372
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800373 ModMplsTtlInstruction() {
sangho3f97a17d2015-01-29 22:56:29 -0800374 }
375
376 @Override
377 public L2SubType subtype() {
378 return L2SubType.DEC_MPLS_TTL;
379 }
380
381 @Override
382 public String toString() {
Yuta HIGUCHIcca5e722015-02-05 14:00:41 -0800383 return toStringHelper(subtype().toString())
384 .toString();
sangho3f97a17d2015-01-29 22:56:29 -0800385 }
386
387 @Override
388 public int hashCode() {
Yuta HIGUCHIcca5e722015-02-05 14:00:41 -0800389 return Objects.hash(type(), subtype());
sangho3f97a17d2015-01-29 22:56:29 -0800390 }
391
392 @Override
393 public boolean equals(Object obj) {
394 if (this == obj) {
395 return true;
396 }
Yuta HIGUCHIcca5e722015-02-05 14:00:41 -0800397 if (obj instanceof ModMplsTtlInstruction) {
398 return true;
sangho3f97a17d2015-01-29 22:56:29 -0800399 }
400 return false;
401 }
402 }
alshabib55a55d92014-09-16 11:59:31 -0700403}