blob: 47e473f6e6d2c9922af351ad2a703578da10867b [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
alshabib99b8fdc2014-09-25 14:30:22 -070018import static com.google.common.base.MoreObjects.toStringHelper;
alshabib55a55d92014-09-16 11:59:31 -070019import static com.google.common.base.Preconditions.checkNotNull;
Brian O'Connorabafb502014-12-02 22:26:20 -080020import static org.onosproject.net.flow.instructions.L2ModificationInstruction.*;
alshabib55a55d92014-09-16 11:59:31 -070021
alshabib8ca53902014-10-07 13:11:17 -070022import java.util.Objects;
23
sangho8995ac52015-02-04 11:29:03 -080024import org.onosproject.core.GroupId;
Brian O'Connorabafb502014-12-02 22:26:20 -080025import org.onosproject.net.PortNumber;
alshabib9af70072015-02-09 14:34:16 -080026import org.onosproject.net.flow.FlowRule;
Brian O'Connorabafb502014-12-02 22:26:20 -080027import org.onosproject.net.flow.instructions.L0ModificationInstruction.L0SubType;
28import org.onosproject.net.flow.instructions.L0ModificationInstruction.ModLambdaInstruction;
29import org.onosproject.net.flow.instructions.L2ModificationInstruction.L2SubType;
30import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
31import org.onosproject.net.flow.instructions.L3ModificationInstruction.L3SubType;
32import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -080033import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPv6FlowLabelInstruction;
sangho3f97a17d2015-01-29 22:56:29 -080034import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModTtlInstruction;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -080035
36import org.onlab.packet.Ethernet;
Pavlin Radoslavov855ea2d2014-10-30 15:32:39 -070037import org.onlab.packet.IpAddress;
Ayaka Koshibea9c199f2014-09-16 16:21:40 -070038import org.onlab.packet.MacAddress;
Michele Santuari4b6019e2014-12-19 11:31:45 +010039import org.onlab.packet.MplsLabel;
Ayaka Koshibea9c199f2014-09-16 16:21:40 -070040import org.onlab.packet.VlanId;
alshabib64231f62014-09-16 17:58:36 -070041
alshabib55a55d92014-09-16 11:59:31 -070042/**
43 * Factory class for creating various traffic treatment instructions.
44 */
45public final class Instructions {
46
47
48 // Ban construction
49 private Instructions() {}
50
51 /**
52 * Creates an output instruction using the specified port number. This can
53 * include logical ports such as CONTROLLER, FLOOD, etc.
54 *
55 * @param number port number
56 * @return output instruction
57 */
58 public static OutputInstruction createOutput(final PortNumber number) {
59 checkNotNull(number, "PortNumber cannot be null");
60 return new OutputInstruction(number);
61 }
62
63 /**
64 * Creates a drop instruction.
65 * @return drop instruction
66 */
67 public static DropInstruction createDrop() {
68 return new DropInstruction();
69 }
70
71 /**
sangho8995ac52015-02-04 11:29:03 -080072 * Creates a group instruction.
73 *
74 * @param groupId Group Id
75 * @return group instruction
76 */
77 public static GroupInstruction createGroup(final GroupId groupId) {
78 checkNotNull(groupId, "GroupId cannot be null");
79 return new GroupInstruction(groupId);
80 }
81
82 /**
Marc De Leenheer49087752014-10-23 13:54:09 -070083 * Creates a l0 modification.
84 * @param lambda the lambda to modify to.
85 * @return a l0 modification
86 */
87 public static L0ModificationInstruction modL0Lambda(short lambda) {
88 checkNotNull(lambda, "L0 lambda cannot be null");
89 return new ModLambdaInstruction(L0SubType.LAMBDA, lambda);
90 }
91
92 /**
alshabib55a55d92014-09-16 11:59:31 -070093 * Creates a l2 src modification.
94 * @param addr the mac address to modify to.
95 * @return a l2 modification
96 */
Ayaka Koshibea9c199f2014-09-16 16:21:40 -070097 public static L2ModificationInstruction modL2Src(MacAddress addr) {
alshabib55a55d92014-09-16 11:59:31 -070098 checkNotNull(addr, "Src l2 address cannot be null");
alshabib99b8fdc2014-09-25 14:30:22 -070099 return new ModEtherInstruction(L2SubType.ETH_SRC, addr);
alshabib55a55d92014-09-16 11:59:31 -0700100 }
101
102 /**
103 * Creates a L2 dst modification.
104 * @param addr the mac address to modify to.
105 * @return a L2 modification
106 */
Ayaka Koshibea9c199f2014-09-16 16:21:40 -0700107 public static L2ModificationInstruction modL2Dst(MacAddress addr) {
alshabib55a55d92014-09-16 11:59:31 -0700108 checkNotNull(addr, "Dst l2 address cannot be null");
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800109 return new ModEtherInstruction(L2SubType.ETH_DST, addr);
alshabib55a55d92014-09-16 11:59:31 -0700110 }
111
112 /**
alshabib7410fea2014-09-16 13:48:39 -0700113 * Creates a Vlan id modification.
114 * @param vlanId the vlan id to modify to.
115 * @return a L2 modification
116 */
Ayaka Koshibea9c199f2014-09-16 16:21:40 -0700117 public static L2ModificationInstruction modVlanId(VlanId vlanId) {
alshabib55a55d92014-09-16 11:59:31 -0700118 checkNotNull(vlanId, "VLAN id cannot be null");
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800119 return new ModVlanIdInstruction(vlanId);
alshabib55a55d92014-09-16 11:59:31 -0700120 }
121
alshabib7410fea2014-09-16 13:48:39 -0700122 /**
123 * Creates a Vlan pcp modification.
124 * @param vlanPcp the pcp to modify to.
125 * @return a L2 modification
126 */
127 public static L2ModificationInstruction modVlanPcp(Byte vlanPcp) {
128 checkNotNull(vlanPcp, "VLAN Pcp cannot be null");
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800129 return new ModVlanPcpInstruction(vlanPcp);
alshabib7410fea2014-09-16 13:48:39 -0700130 }
131
132 /**
alshabibab21b2d2015-03-04 18:35:33 -0800133 * Strips the VLAN tag if one is present.
134 * @return a L2 modification
135 */
136 public static L2ModificationInstruction stripVlanId() {
137 return new StripVlanInstruction();
138 }
139
140 /**
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800141 * Creates a MPLS label modification.
142 * @param mplsLabel to set.
143 * @return a L2 Modification
144 */
Michele Santuari4b6019e2014-12-19 11:31:45 +0100145 public static L2ModificationInstruction modMplsLabel(MplsLabel mplsLabel) {
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800146 checkNotNull(mplsLabel, "MPLS label cannot be null");
147 return new ModMplsLabelInstruction(mplsLabel);
148 }
sangho3f97a17d2015-01-29 22:56:29 -0800149
150 /**
151 * Creates a MPLS TTL modification.
152 *
153 * @return a L2 Modification
154 */
155 public static L2ModificationInstruction decMplsTtl() {
156 return new ModMplsTtlInstruction();
157 }
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800158
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800159 /**
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800160 * Creates a L3 IPv4 src modification.
161 *
162 * @param addr the IPv4 address to modify to
alshabib7410fea2014-09-16 13:48:39 -0700163 * @return a L3 modification
164 */
Pavlin Radoslavov855ea2d2014-10-30 15:32:39 -0700165 public static L3ModificationInstruction modL3Src(IpAddress addr) {
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800166 checkNotNull(addr, "Src l3 IPv4 address cannot be null");
167 return new ModIPInstruction(L3SubType.IPV4_SRC, addr);
alshabib7410fea2014-09-16 13:48:39 -0700168 }
169
170 /**
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800171 * Creates a L3 IPv4 dst modification.
172 *
173 * @param addr the IPv4 address to modify to
alshabib7410fea2014-09-16 13:48:39 -0700174 * @return a L3 modification
175 */
Pavlin Radoslavov855ea2d2014-10-30 15:32:39 -0700176 public static L3ModificationInstruction modL3Dst(IpAddress addr) {
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800177 checkNotNull(addr, "Dst l3 IPv4 address cannot be null");
178 return new ModIPInstruction(L3SubType.IPV4_DST, addr);
179 }
180
181 /**
182 * Creates a L3 IPv6 src modification.
183 *
184 * @param addr the IPv6 address to modify to
185 * @return a L3 modification
186 */
187 public static L3ModificationInstruction modL3IPv6Src(IpAddress addr) {
188 checkNotNull(addr, "Src l3 IPv6 address cannot be null");
189 return new ModIPInstruction(L3SubType.IPV6_SRC, addr);
190 }
191
192 /**
193 * Creates a L3 IPv6 dst modification.
194 *
195 * @param addr the IPv6 address to modify to
196 * @return a L3 modification
197 */
198 public static L3ModificationInstruction modL3IPv6Dst(IpAddress addr) {
199 checkNotNull(addr, "Dst l3 IPv6 address cannot be null");
200 return new ModIPInstruction(L3SubType.IPV6_DST, addr);
201 }
202
203 /**
204 * Creates a L3 IPv6 Flow Label modification.
205 *
206 * @param flowLabel the IPv6 flow label to modify to (20 bits)
207 * @return a L3 modification
208 */
209 public static L3ModificationInstruction modL3IPv6FlowLabel(int flowLabel) {
210 return new ModIPv6FlowLabelInstruction(flowLabel);
alshabib7410fea2014-09-16 13:48:39 -0700211 }
212
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800213 /**
sangho3f97a17d2015-01-29 22:56:29 -0800214 * Creates a L3 TTL modification.
215 * @return a L3 modification
216 */
217 public static L3ModificationInstruction decNwTtl() {
218 return new ModTtlInstruction(L3SubType.DEC_TTL);
219 }
220
221 /**
222 * Creates a L3 TTL modification.
223 * @return a L3 modification
224 */
225 public static L3ModificationInstruction copyTtlOut() {
226 return new ModTtlInstruction(L3SubType.TTL_OUT);
227 }
228
229 /**
230 * Creates a L3 TTL modification.
231 * @return a L3 modification
232 */
233 public static L3ModificationInstruction copyTtlIn() {
234 return new ModTtlInstruction(L3SubType.TTL_IN);
235 }
236
237 /**
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800238 * Creates a mpls header instruction.
239 * @return a L2 modification.
240 */
241 public static Instruction pushMpls() {
242 return new PushHeaderInstructions(L2SubType.MPLS_PUSH,
Yuta HIGUCHI32a53c52015-02-08 01:25:40 -0800243 Ethernet.MPLS_UNICAST);
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800244 }
245
246 /**
247 * Creates a mpls header instruction.
248 * @return a L2 modification.
249 */
250 public static Instruction popMpls() {
251 return new PushHeaderInstructions(L2SubType.MPLS_POP,
Yuta HIGUCHI32a53c52015-02-08 01:25:40 -0800252 Ethernet.MPLS_UNICAST);
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800253 }
alshabib7410fea2014-09-16 13:48:39 -0700254
sangho3f97a17d2015-01-29 22:56:29 -0800255 /**
256 * Creates a mpls header instruction.
257 *
258 * @param etherType Ethernet type to set
259 * @return a L2 modification.
260 */
261 public static Instruction popMpls(Short etherType) {
262 checkNotNull(etherType, "Ethernet type cannot be null");
Yuta HIGUCHI32a53c52015-02-08 01:25:40 -0800263 return new PushHeaderInstructions(L2SubType.MPLS_POP, etherType);
sangho3f97a17d2015-01-29 22:56:29 -0800264 }
265
Saurav Dasfbe25c52015-03-04 11:12:00 -0800266 /**
267 * Creates a vlan header instruction.
268 * @return a L2 modification.
269 */
270 public static Instruction popVlan() {
271 return new PopVlanInstruction(L2SubType.VLAN_POP);
272 }
273
274 /**
275 * Sends the packet to the table described in 'type'.
Thomas Vachuska3e2b6512015-03-05 09:25:03 -0800276 * @param type flow rule table type
277 * @return table type transition instruction
Saurav Dasfbe25c52015-03-04 11:12:00 -0800278 */
alshabib9af70072015-02-09 14:34:16 -0800279 public static Instruction transition(FlowRule.Type type) {
280 checkNotNull(type, "Table type cannot be null");
281 return new TableTypeTransition(type);
282 }
283
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800284 /**
285 * Drop instruction.
alshabib55a55d92014-09-16 11:59:31 -0700286 */
alshabib55a55d92014-09-16 11:59:31 -0700287 public static final class DropInstruction implements Instruction {
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800288
289 private DropInstruction() {}
290
alshabib55a55d92014-09-16 11:59:31 -0700291 @Override
292 public Type type() {
293 return Type.DROP;
294 }
alshabib99b8fdc2014-09-25 14:30:22 -0700295
296 @Override
297 public String toString() {
alshabib346b5b32015-03-06 00:42:16 -0800298 return toStringHelper(type().toString()).toString();
alshabib99b8fdc2014-09-25 14:30:22 -0700299
300 }
alshabib8ca53902014-10-07 13:11:17 -0700301
302 @Override
303 public int hashCode() {
304 return Objects.hash(type());
305 }
306
307 @Override
308 public boolean equals(Object obj) {
309 if (this == obj) {
310 return true;
311 }
312 if (obj instanceof DropInstruction) {
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800313 return true;
alshabib8ca53902014-10-07 13:11:17 -0700314 }
315 return false;
316 }
alshabib55a55d92014-09-16 11:59:31 -0700317 }
318
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800319 /**
320 * Output Instruction.
sangho8995ac52015-02-04 11:29:03 -0800321 */
alshabib55a55d92014-09-16 11:59:31 -0700322 public static final class OutputInstruction implements Instruction {
323 private final PortNumber port;
324
325 private OutputInstruction(PortNumber port) {
326 this.port = port;
327 }
328
329 public PortNumber port() {
330 return port;
331 }
332
333 @Override
334 public Type type() {
335 return Type.OUTPUT;
336 }
alshabib99b8fdc2014-09-25 14:30:22 -0700337 @Override
338 public String toString() {
339 return toStringHelper(type().toString())
340 .add("port", port).toString();
341 }
alshabib8ca53902014-10-07 13:11:17 -0700342
343 @Override
344 public int hashCode() {
Thomas Vachuska9b2da212014-11-10 19:30:25 -0800345 return Objects.hash(type(), port);
alshabib8ca53902014-10-07 13:11:17 -0700346 }
347
348 @Override
349 public boolean equals(Object obj) {
350 if (this == obj) {
351 return true;
352 }
353 if (obj instanceof OutputInstruction) {
354 OutputInstruction that = (OutputInstruction) obj;
Yuta HIGUCHI4ce65292014-11-01 12:09:55 -0700355 return Objects.equals(port, that.port);
alshabib8ca53902014-10-07 13:11:17 -0700356
357 }
358 return false;
359 }
alshabib55a55d92014-09-16 11:59:31 -0700360 }
361
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800362 /**
363 * Group Instruction.
sangho8995ac52015-02-04 11:29:03 -0800364 */
sangho8995ac52015-02-04 11:29:03 -0800365 public static final class GroupInstruction implements Instruction {
366 private final GroupId groupId;
367
368 private GroupInstruction(GroupId groupId) {
369 this.groupId = groupId;
370 }
371
372 public GroupId groupId() {
373 return groupId;
374 }
375
376 @Override
377 public Type type() {
378 return Type.GROUP;
379 }
alshabib9af70072015-02-09 14:34:16 -0800380
sangho8995ac52015-02-04 11:29:03 -0800381 @Override
382 public String toString() {
383 return toStringHelper(type().toString())
384 .add("group ID", groupId.id()).toString();
385 }
386
387 @Override
388 public int hashCode() {
389 return Objects.hash(type(), groupId);
390 }
391
392 @Override
393 public boolean equals(Object obj) {
394 if (this == obj) {
395 return true;
396 }
397 if (obj instanceof GroupInstruction) {
398 GroupInstruction that = (GroupInstruction) obj;
399 return Objects.equals(groupId, that.groupId);
400
401 }
402 return false;
403 }
404 }
405
alshabib9af70072015-02-09 14:34:16 -0800406 // FIXME: Temporary support for this. This should probably become it's own
407 // type like other instructions.
408 public static class TableTypeTransition implements Instruction {
409 private final FlowRule.Type tableType;
410
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800411 TableTypeTransition(FlowRule.Type type) {
alshabib9af70072015-02-09 14:34:16 -0800412 this.tableType = type;
413 }
414
415 @Override
416 public Type type() {
417 return Type.TABLE;
418 }
419
420 public FlowRule.Type tableType() {
421 return this.tableType;
422 }
423
424 @Override
425 public String toString() {
426 return toStringHelper(type().toString())
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800427 .add("tableType", this.tableType).toString();
alshabib9af70072015-02-09 14:34:16 -0800428 }
429
430 @Override
431 public int hashCode() {
432 return Objects.hash(type(), tableType);
433 }
434
435 @Override
436 public boolean equals(Object obj) {
437 if (this == obj) {
438 return true;
439 }
440 if (obj instanceof TableTypeTransition) {
441 TableTypeTransition that = (TableTypeTransition) obj;
442 return Objects.equals(tableType, that.tableType);
443
444 }
445 return false;
446 }
447
448 }
alshabib55a55d92014-09-16 11:59:31 -0700449}
alshabib8ca53902014-10-07 13:11:17 -0700450
451