blob: 3a0566df9ed1bd9617bcac0b640c72e48063eeba [file] [log] [blame]
Thomas Vachuska83e090e2014-10-22 14:25:35 -07001/*
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07002 * Copyright 2014 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
Jonathan Hart54b406b2015-03-06 16:24:14 -080018import org.onlab.packet.Ethernet;
19import org.onlab.packet.IpAddress;
20import org.onlab.packet.MacAddress;
21import org.onlab.packet.MplsLabel;
22import org.onlab.packet.VlanId;
sangho8995ac52015-02-04 11:29:03 -080023import org.onosproject.core.GroupId;
Brian O'Connorabafb502014-12-02 22:26:20 -080024import org.onosproject.net.PortNumber;
alshabib9af70072015-02-09 14:34:16 -080025import org.onosproject.net.flow.FlowRule;
Brian O'Connorabafb502014-12-02 22:26:20 -080026import org.onosproject.net.flow.instructions.L0ModificationInstruction.L0SubType;
27import org.onosproject.net.flow.instructions.L0ModificationInstruction.ModLambdaInstruction;
28import org.onosproject.net.flow.instructions.L2ModificationInstruction.L2SubType;
29import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
30import org.onosproject.net.flow.instructions.L3ModificationInstruction.L3SubType;
31import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -080032import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPv6FlowLabelInstruction;
sangho3f97a17d2015-01-29 22:56:29 -080033import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModTtlInstruction;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -080034
Jonathan Hart54b406b2015-03-06 16:24:14 -080035import java.util.Objects;
36
37import static com.google.common.base.MoreObjects.toStringHelper;
38import static com.google.common.base.Preconditions.checkNotNull;
39import static org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsLabelInstruction;
40import static org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsTtlInstruction;
41import static org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
42import static org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction;
43import static org.onosproject.net.flow.instructions.L2ModificationInstruction.PopVlanInstruction;
44import static org.onosproject.net.flow.instructions.L2ModificationInstruction.PushHeaderInstructions;
45import static org.onosproject.net.flow.instructions.L2ModificationInstruction.StripVlanInstruction;
alshabib64231f62014-09-16 17:58:36 -070046
alshabib55a55d92014-09-16 11:59:31 -070047/**
48 * Factory class for creating various traffic treatment instructions.
49 */
50public final class Instructions {
51
52
53 // Ban construction
54 private Instructions() {}
55
56 /**
57 * Creates an output instruction using the specified port number. This can
58 * include logical ports such as CONTROLLER, FLOOD, etc.
59 *
60 * @param number port number
61 * @return output instruction
62 */
63 public static OutputInstruction createOutput(final PortNumber number) {
64 checkNotNull(number, "PortNumber cannot be null");
65 return new OutputInstruction(number);
66 }
67
68 /**
69 * Creates a drop instruction.
Jonathan Hart54b406b2015-03-06 16:24:14 -080070 *
alshabib55a55d92014-09-16 11:59:31 -070071 * @return drop instruction
72 */
73 public static DropInstruction createDrop() {
74 return new DropInstruction();
75 }
76
77 /**
sangho8995ac52015-02-04 11:29:03 -080078 * Creates a group instruction.
79 *
80 * @param groupId Group Id
81 * @return group instruction
82 */
83 public static GroupInstruction createGroup(final GroupId groupId) {
84 checkNotNull(groupId, "GroupId cannot be null");
85 return new GroupInstruction(groupId);
86 }
87
88 /**
Marc De Leenheer49087752014-10-23 13:54:09 -070089 * Creates a l0 modification.
Jonathan Hart54b406b2015-03-06 16:24:14 -080090 *
91 * @param lambda the lambda to modify to
Marc De Leenheer49087752014-10-23 13:54:09 -070092 * @return a l0 modification
93 */
94 public static L0ModificationInstruction modL0Lambda(short lambda) {
95 checkNotNull(lambda, "L0 lambda cannot be null");
96 return new ModLambdaInstruction(L0SubType.LAMBDA, lambda);
97 }
98
99 /**
alshabib55a55d92014-09-16 11:59:31 -0700100 * Creates a l2 src modification.
Jonathan Hart54b406b2015-03-06 16:24:14 -0800101 *
102 * @param addr the mac address to modify to
alshabib55a55d92014-09-16 11:59:31 -0700103 * @return a l2 modification
104 */
Ayaka Koshibea9c199f2014-09-16 16:21:40 -0700105 public static L2ModificationInstruction modL2Src(MacAddress addr) {
alshabib55a55d92014-09-16 11:59:31 -0700106 checkNotNull(addr, "Src l2 address cannot be null");
alshabib99b8fdc2014-09-25 14:30:22 -0700107 return new ModEtherInstruction(L2SubType.ETH_SRC, addr);
alshabib55a55d92014-09-16 11:59:31 -0700108 }
109
110 /**
111 * Creates a L2 dst modification.
Jonathan Hart54b406b2015-03-06 16:24:14 -0800112 *
113 * @param addr the mac address to modify to
alshabib55a55d92014-09-16 11:59:31 -0700114 * @return a L2 modification
115 */
Ayaka Koshibea9c199f2014-09-16 16:21:40 -0700116 public static L2ModificationInstruction modL2Dst(MacAddress addr) {
alshabib55a55d92014-09-16 11:59:31 -0700117 checkNotNull(addr, "Dst l2 address cannot be null");
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800118 return new ModEtherInstruction(L2SubType.ETH_DST, addr);
alshabib55a55d92014-09-16 11:59:31 -0700119 }
120
121 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800122 * Creates a VLAN ID modification.
123 *
124 * @param vlanId the VLAN ID to modify to
alshabib7410fea2014-09-16 13:48:39 -0700125 * @return a L2 modification
126 */
Ayaka Koshibea9c199f2014-09-16 16:21:40 -0700127 public static L2ModificationInstruction modVlanId(VlanId vlanId) {
alshabib55a55d92014-09-16 11:59:31 -0700128 checkNotNull(vlanId, "VLAN id cannot be null");
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800129 return new ModVlanIdInstruction(vlanId);
alshabib55a55d92014-09-16 11:59:31 -0700130 }
131
alshabib7410fea2014-09-16 13:48:39 -0700132 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800133 * Creates a VLAN PCP modification.
134 *
135 * @param vlanPcp the PCP to modify to
alshabib7410fea2014-09-16 13:48:39 -0700136 * @return a L2 modification
137 */
138 public static L2ModificationInstruction modVlanPcp(Byte vlanPcp) {
139 checkNotNull(vlanPcp, "VLAN Pcp cannot be null");
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800140 return new ModVlanPcpInstruction(vlanPcp);
alshabib7410fea2014-09-16 13:48:39 -0700141 }
142
143 /**
alshabibab21b2d2015-03-04 18:35:33 -0800144 * Strips the VLAN tag if one is present.
Jonathan Hart54b406b2015-03-06 16:24:14 -0800145 *
alshabibab21b2d2015-03-04 18:35:33 -0800146 * @return a L2 modification
147 */
148 public static L2ModificationInstruction stripVlanId() {
149 return new StripVlanInstruction();
150 }
151
152 /**
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800153 * Creates a MPLS label modification.
Jonathan Hart54b406b2015-03-06 16:24:14 -0800154 *
155 * @param mplsLabel MPLS label to set
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800156 * @return a L2 Modification
157 */
Michele Santuari4b6019e2014-12-19 11:31:45 +0100158 public static L2ModificationInstruction modMplsLabel(MplsLabel mplsLabel) {
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800159 checkNotNull(mplsLabel, "MPLS label cannot be null");
160 return new ModMplsLabelInstruction(mplsLabel);
161 }
sangho3f97a17d2015-01-29 22:56:29 -0800162
163 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800164 * Creates a MPLS decrement TTL modification.
sangho3f97a17d2015-01-29 22:56:29 -0800165 *
166 * @return a L2 Modification
167 */
168 public static L2ModificationInstruction decMplsTtl() {
169 return new ModMplsTtlInstruction();
170 }
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800171
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800172 /**
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800173 * Creates a L3 IPv4 src modification.
174 *
175 * @param addr the IPv4 address to modify to
alshabib7410fea2014-09-16 13:48:39 -0700176 * @return a L3 modification
177 */
Pavlin Radoslavov855ea2d2014-10-30 15:32:39 -0700178 public static L3ModificationInstruction modL3Src(IpAddress addr) {
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800179 checkNotNull(addr, "Src l3 IPv4 address cannot be null");
180 return new ModIPInstruction(L3SubType.IPV4_SRC, addr);
alshabib7410fea2014-09-16 13:48:39 -0700181 }
182
183 /**
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800184 * Creates a L3 IPv4 dst modification.
185 *
186 * @param addr the IPv4 address to modify to
alshabib7410fea2014-09-16 13:48:39 -0700187 * @return a L3 modification
188 */
Pavlin Radoslavov855ea2d2014-10-30 15:32:39 -0700189 public static L3ModificationInstruction modL3Dst(IpAddress addr) {
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800190 checkNotNull(addr, "Dst l3 IPv4 address cannot be null");
191 return new ModIPInstruction(L3SubType.IPV4_DST, addr);
192 }
193
194 /**
195 * Creates a L3 IPv6 src modification.
196 *
197 * @param addr the IPv6 address to modify to
198 * @return a L3 modification
199 */
200 public static L3ModificationInstruction modL3IPv6Src(IpAddress addr) {
201 checkNotNull(addr, "Src l3 IPv6 address cannot be null");
202 return new ModIPInstruction(L3SubType.IPV6_SRC, addr);
203 }
204
205 /**
206 * Creates a L3 IPv6 dst modification.
207 *
208 * @param addr the IPv6 address to modify to
209 * @return a L3 modification
210 */
211 public static L3ModificationInstruction modL3IPv6Dst(IpAddress addr) {
212 checkNotNull(addr, "Dst l3 IPv6 address cannot be null");
213 return new ModIPInstruction(L3SubType.IPV6_DST, addr);
214 }
215
216 /**
217 * Creates a L3 IPv6 Flow Label modification.
218 *
219 * @param flowLabel the IPv6 flow label to modify to (20 bits)
220 * @return a L3 modification
221 */
222 public static L3ModificationInstruction modL3IPv6FlowLabel(int flowLabel) {
223 return new ModIPv6FlowLabelInstruction(flowLabel);
alshabib7410fea2014-09-16 13:48:39 -0700224 }
225
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800226 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800227 * Creates a L3 decrement TTL modification.
228 *
sangho3f97a17d2015-01-29 22:56:29 -0800229 * @return a L3 modification
230 */
231 public static L3ModificationInstruction decNwTtl() {
232 return new ModTtlInstruction(L3SubType.DEC_TTL);
233 }
234
235 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800236 * Creates a L3 copy TTL to outer header modification.
237 *
sangho3f97a17d2015-01-29 22:56:29 -0800238 * @return a L3 modification
239 */
240 public static L3ModificationInstruction copyTtlOut() {
241 return new ModTtlInstruction(L3SubType.TTL_OUT);
242 }
243
244 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800245 * Creates a L3 copy TTL to inner header modification.
246 *
sangho3f97a17d2015-01-29 22:56:29 -0800247 * @return a L3 modification
248 */
249 public static L3ModificationInstruction copyTtlIn() {
250 return new ModTtlInstruction(L3SubType.TTL_IN);
251 }
252
253 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800254 * Creates a push MPLS header instruction.
255 *
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800256 * @return a L2 modification.
257 */
258 public static Instruction pushMpls() {
259 return new PushHeaderInstructions(L2SubType.MPLS_PUSH,
Yuta HIGUCHI32a53c52015-02-08 01:25:40 -0800260 Ethernet.MPLS_UNICAST);
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800261 }
262
263 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800264 * Creates a pop MPLS header instruction.
265 *
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800266 * @return a L2 modification.
267 */
268 public static Instruction popMpls() {
269 return new PushHeaderInstructions(L2SubType.MPLS_POP,
Yuta HIGUCHI32a53c52015-02-08 01:25:40 -0800270 Ethernet.MPLS_UNICAST);
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800271 }
alshabib7410fea2014-09-16 13:48:39 -0700272
sangho3f97a17d2015-01-29 22:56:29 -0800273 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800274 * Creates a pop MPLS header instruction with a particular ethertype.
sangho3f97a17d2015-01-29 22:56:29 -0800275 *
276 * @param etherType Ethernet type to set
277 * @return a L2 modification.
278 */
279 public static Instruction popMpls(Short etherType) {
280 checkNotNull(etherType, "Ethernet type cannot be null");
Yuta HIGUCHI32a53c52015-02-08 01:25:40 -0800281 return new PushHeaderInstructions(L2SubType.MPLS_POP, etherType);
sangho3f97a17d2015-01-29 22:56:29 -0800282 }
283
Saurav Dasfbe25c52015-03-04 11:12:00 -0800284 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800285 * Creates a pop VLAN header instruction.
286 *
287 * @return a L2 modification
Saurav Dasfbe25c52015-03-04 11:12:00 -0800288 */
289 public static Instruction popVlan() {
290 return new PopVlanInstruction(L2SubType.VLAN_POP);
291 }
292
293 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800294 * Creates a push VLAN header instruction.
295 *
296 * @return a L2 modification
297 */
298 public static Instruction pushVlan() {
299 return new PushHeaderInstructions(L2SubType.VLAN_PUSH, Ethernet.TYPE_VLAN);
300 }
301
302 /**
Saurav Dasfbe25c52015-03-04 11:12:00 -0800303 * Sends the packet to the table described in 'type'.
Jonathan Hart54b406b2015-03-06 16:24:14 -0800304 *
Thomas Vachuska3e2b6512015-03-05 09:25:03 -0800305 * @param type flow rule table type
306 * @return table type transition instruction
Saurav Dasfbe25c52015-03-04 11:12:00 -0800307 */
alshabib9af70072015-02-09 14:34:16 -0800308 public static Instruction transition(FlowRule.Type type) {
309 checkNotNull(type, "Table type cannot be null");
310 return new TableTypeTransition(type);
311 }
312
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800313 /**
314 * Drop instruction.
alshabib55a55d92014-09-16 11:59:31 -0700315 */
alshabib55a55d92014-09-16 11:59:31 -0700316 public static final class DropInstruction implements Instruction {
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800317
318 private DropInstruction() {}
319
alshabib55a55d92014-09-16 11:59:31 -0700320 @Override
321 public Type type() {
322 return Type.DROP;
323 }
alshabib99b8fdc2014-09-25 14:30:22 -0700324
325 @Override
326 public String toString() {
alshabib346b5b32015-03-06 00:42:16 -0800327 return toStringHelper(type().toString()).toString();
alshabib99b8fdc2014-09-25 14:30:22 -0700328 }
alshabib8ca53902014-10-07 13:11:17 -0700329
330 @Override
331 public int hashCode() {
332 return Objects.hash(type());
333 }
334
335 @Override
336 public boolean equals(Object obj) {
337 if (this == obj) {
338 return true;
339 }
340 if (obj instanceof DropInstruction) {
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800341 return true;
alshabib8ca53902014-10-07 13:11:17 -0700342 }
343 return false;
344 }
alshabib55a55d92014-09-16 11:59:31 -0700345 }
346
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800347 /**
348 * Output Instruction.
sangho8995ac52015-02-04 11:29:03 -0800349 */
alshabib55a55d92014-09-16 11:59:31 -0700350 public static final class OutputInstruction implements Instruction {
351 private final PortNumber port;
352
353 private OutputInstruction(PortNumber port) {
354 this.port = port;
355 }
356
357 public PortNumber port() {
358 return port;
359 }
360
361 @Override
362 public Type type() {
363 return Type.OUTPUT;
364 }
alshabib99b8fdc2014-09-25 14:30:22 -0700365 @Override
366 public String toString() {
367 return toStringHelper(type().toString())
368 .add("port", port).toString();
369 }
alshabib8ca53902014-10-07 13:11:17 -0700370
371 @Override
372 public int hashCode() {
Thomas Vachuska9b2da212014-11-10 19:30:25 -0800373 return Objects.hash(type(), port);
alshabib8ca53902014-10-07 13:11:17 -0700374 }
375
376 @Override
377 public boolean equals(Object obj) {
378 if (this == obj) {
379 return true;
380 }
381 if (obj instanceof OutputInstruction) {
382 OutputInstruction that = (OutputInstruction) obj;
Yuta HIGUCHI4ce65292014-11-01 12:09:55 -0700383 return Objects.equals(port, that.port);
alshabib8ca53902014-10-07 13:11:17 -0700384
385 }
386 return false;
387 }
alshabib55a55d92014-09-16 11:59:31 -0700388 }
389
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800390 /**
391 * Group Instruction.
sangho8995ac52015-02-04 11:29:03 -0800392 */
sangho8995ac52015-02-04 11:29:03 -0800393 public static final class GroupInstruction implements Instruction {
394 private final GroupId groupId;
395
396 private GroupInstruction(GroupId groupId) {
397 this.groupId = groupId;
398 }
399
400 public GroupId groupId() {
401 return groupId;
402 }
403
404 @Override
405 public Type type() {
406 return Type.GROUP;
407 }
alshabib9af70072015-02-09 14:34:16 -0800408
sangho8995ac52015-02-04 11:29:03 -0800409 @Override
410 public String toString() {
411 return toStringHelper(type().toString())
412 .add("group ID", groupId.id()).toString();
413 }
414
415 @Override
416 public int hashCode() {
417 return Objects.hash(type(), groupId);
418 }
419
420 @Override
421 public boolean equals(Object obj) {
422 if (this == obj) {
423 return true;
424 }
425 if (obj instanceof GroupInstruction) {
426 GroupInstruction that = (GroupInstruction) obj;
427 return Objects.equals(groupId, that.groupId);
428
429 }
430 return false;
431 }
432 }
433
alshabib9af70072015-02-09 14:34:16 -0800434 // FIXME: Temporary support for this. This should probably become it's own
435 // type like other instructions.
436 public static class TableTypeTransition implements Instruction {
437 private final FlowRule.Type tableType;
438
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800439 TableTypeTransition(FlowRule.Type type) {
alshabib9af70072015-02-09 14:34:16 -0800440 this.tableType = type;
441 }
442
443 @Override
444 public Type type() {
445 return Type.TABLE;
446 }
447
448 public FlowRule.Type tableType() {
449 return this.tableType;
450 }
451
452 @Override
453 public String toString() {
454 return toStringHelper(type().toString())
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800455 .add("tableType", this.tableType).toString();
alshabib9af70072015-02-09 14:34:16 -0800456 }
457
458 @Override
459 public int hashCode() {
460 return Objects.hash(type(), tableType);
461 }
462
463 @Override
464 public boolean equals(Object obj) {
465 if (this == obj) {
466 return true;
467 }
468 if (obj instanceof TableTypeTransition) {
469 TableTypeTransition that = (TableTypeTransition) obj;
470 return Objects.equals(tableType, that.tableType);
471
472 }
473 return false;
474 }
475
476 }
alshabib55a55d92014-09-16 11:59:31 -0700477}
alshabib8ca53902014-10-07 13:11:17 -0700478
479