blob: e0a5ca63a952b2ccac6a527d47890b6f30927913 [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 /**
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800133 * Creates a MPLS label modification.
134 * @param mplsLabel to set.
135 * @return a L2 Modification
136 */
Michele Santuari4b6019e2014-12-19 11:31:45 +0100137 public static L2ModificationInstruction modMplsLabel(MplsLabel mplsLabel) {
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800138 checkNotNull(mplsLabel, "MPLS label cannot be null");
139 return new ModMplsLabelInstruction(mplsLabel);
140 }
sangho3f97a17d2015-01-29 22:56:29 -0800141
142 /**
143 * Creates a MPLS TTL modification.
144 *
145 * @return a L2 Modification
146 */
147 public static L2ModificationInstruction decMplsTtl() {
148 return new ModMplsTtlInstruction();
149 }
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800150
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800151 /**
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800152 * Creates a L3 IPv4 src modification.
153 *
154 * @param addr the IPv4 address to modify to
alshabib7410fea2014-09-16 13:48:39 -0700155 * @return a L3 modification
156 */
Pavlin Radoslavov855ea2d2014-10-30 15:32:39 -0700157 public static L3ModificationInstruction modL3Src(IpAddress addr) {
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800158 checkNotNull(addr, "Src l3 IPv4 address cannot be null");
159 return new ModIPInstruction(L3SubType.IPV4_SRC, addr);
alshabib7410fea2014-09-16 13:48:39 -0700160 }
161
162 /**
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800163 * Creates a L3 IPv4 dst modification.
164 *
165 * @param addr the IPv4 address to modify to
alshabib7410fea2014-09-16 13:48:39 -0700166 * @return a L3 modification
167 */
Pavlin Radoslavov855ea2d2014-10-30 15:32:39 -0700168 public static L3ModificationInstruction modL3Dst(IpAddress addr) {
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800169 checkNotNull(addr, "Dst l3 IPv4 address cannot be null");
170 return new ModIPInstruction(L3SubType.IPV4_DST, addr);
171 }
172
173 /**
174 * Creates a L3 IPv6 src modification.
175 *
176 * @param addr the IPv6 address to modify to
177 * @return a L3 modification
178 */
179 public static L3ModificationInstruction modL3IPv6Src(IpAddress addr) {
180 checkNotNull(addr, "Src l3 IPv6 address cannot be null");
181 return new ModIPInstruction(L3SubType.IPV6_SRC, addr);
182 }
183
184 /**
185 * Creates a L3 IPv6 dst modification.
186 *
187 * @param addr the IPv6 address to modify to
188 * @return a L3 modification
189 */
190 public static L3ModificationInstruction modL3IPv6Dst(IpAddress addr) {
191 checkNotNull(addr, "Dst l3 IPv6 address cannot be null");
192 return new ModIPInstruction(L3SubType.IPV6_DST, addr);
193 }
194
195 /**
196 * Creates a L3 IPv6 Flow Label modification.
197 *
198 * @param flowLabel the IPv6 flow label to modify to (20 bits)
199 * @return a L3 modification
200 */
201 public static L3ModificationInstruction modL3IPv6FlowLabel(int flowLabel) {
202 return new ModIPv6FlowLabelInstruction(flowLabel);
alshabib7410fea2014-09-16 13:48:39 -0700203 }
204
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800205 /**
sangho3f97a17d2015-01-29 22:56:29 -0800206 * Creates a L3 TTL modification.
207 * @return a L3 modification
208 */
209 public static L3ModificationInstruction decNwTtl() {
210 return new ModTtlInstruction(L3SubType.DEC_TTL);
211 }
212
213 /**
214 * Creates a L3 TTL modification.
215 * @return a L3 modification
216 */
217 public static L3ModificationInstruction copyTtlOut() {
218 return new ModTtlInstruction(L3SubType.TTL_OUT);
219 }
220
221 /**
222 * Creates a L3 TTL modification.
223 * @return a L3 modification
224 */
225 public static L3ModificationInstruction copyTtlIn() {
226 return new ModTtlInstruction(L3SubType.TTL_IN);
227 }
228
229 /**
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800230 * Creates a mpls header instruction.
231 * @return a L2 modification.
232 */
233 public static Instruction pushMpls() {
234 return new PushHeaderInstructions(L2SubType.MPLS_PUSH,
Yuta HIGUCHI32a53c52015-02-08 01:25:40 -0800235 Ethernet.MPLS_UNICAST);
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800236 }
237
238 /**
239 * Creates a mpls header instruction.
240 * @return a L2 modification.
241 */
242 public static Instruction popMpls() {
243 return new PushHeaderInstructions(L2SubType.MPLS_POP,
Yuta HIGUCHI32a53c52015-02-08 01:25:40 -0800244 Ethernet.MPLS_UNICAST);
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800245 }
alshabib7410fea2014-09-16 13:48:39 -0700246
sangho3f97a17d2015-01-29 22:56:29 -0800247 /**
248 * Creates a mpls header instruction.
249 *
250 * @param etherType Ethernet type to set
251 * @return a L2 modification.
252 */
253 public static Instruction popMpls(Short etherType) {
254 checkNotNull(etherType, "Ethernet type cannot be null");
Yuta HIGUCHI32a53c52015-02-08 01:25:40 -0800255 return new PushHeaderInstructions(L2SubType.MPLS_POP, etherType);
sangho3f97a17d2015-01-29 22:56:29 -0800256 }
257
Saurav Dasfbe25c52015-03-04 11:12:00 -0800258 /**
259 * Creates a vlan header instruction.
260 * @return a L2 modification.
261 */
262 public static Instruction popVlan() {
263 return new PopVlanInstruction(L2SubType.VLAN_POP);
264 }
265
266 /**
267 * Sends the packet to the table described in 'type'.
268 * @param type
269 * @return
270 */
alshabib9af70072015-02-09 14:34:16 -0800271 public static Instruction transition(FlowRule.Type type) {
272 checkNotNull(type, "Table type cannot be null");
273 return new TableTypeTransition(type);
274 }
275
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800276 /**
277 * Drop instruction.
alshabib55a55d92014-09-16 11:59:31 -0700278 */
alshabib55a55d92014-09-16 11:59:31 -0700279 public static final class DropInstruction implements Instruction {
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800280
281 private DropInstruction() {}
282
alshabib55a55d92014-09-16 11:59:31 -0700283 @Override
284 public Type type() {
285 return Type.DROP;
286 }
alshabib99b8fdc2014-09-25 14:30:22 -0700287
288 @Override
289 public String toString() {
290 return toStringHelper(type()).toString();
291
292 }
alshabib8ca53902014-10-07 13:11:17 -0700293
294 @Override
295 public int hashCode() {
296 return Objects.hash(type());
297 }
298
299 @Override
300 public boolean equals(Object obj) {
301 if (this == obj) {
302 return true;
303 }
304 if (obj instanceof DropInstruction) {
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800305 return true;
alshabib8ca53902014-10-07 13:11:17 -0700306 }
307 return false;
308 }
alshabib55a55d92014-09-16 11:59:31 -0700309 }
310
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800311 /**
312 * Output Instruction.
sangho8995ac52015-02-04 11:29:03 -0800313 */
alshabib55a55d92014-09-16 11:59:31 -0700314 public static final class OutputInstruction implements Instruction {
315 private final PortNumber port;
316
317 private OutputInstruction(PortNumber port) {
318 this.port = port;
319 }
320
321 public PortNumber port() {
322 return port;
323 }
324
325 @Override
326 public Type type() {
327 return Type.OUTPUT;
328 }
alshabib99b8fdc2014-09-25 14:30:22 -0700329 @Override
330 public String toString() {
331 return toStringHelper(type().toString())
332 .add("port", port).toString();
333 }
alshabib8ca53902014-10-07 13:11:17 -0700334
335 @Override
336 public int hashCode() {
Thomas Vachuska9b2da212014-11-10 19:30:25 -0800337 return Objects.hash(type(), port);
alshabib8ca53902014-10-07 13:11:17 -0700338 }
339
340 @Override
341 public boolean equals(Object obj) {
342 if (this == obj) {
343 return true;
344 }
345 if (obj instanceof OutputInstruction) {
346 OutputInstruction that = (OutputInstruction) obj;
Yuta HIGUCHI4ce65292014-11-01 12:09:55 -0700347 return Objects.equals(port, that.port);
alshabib8ca53902014-10-07 13:11:17 -0700348
349 }
350 return false;
351 }
alshabib55a55d92014-09-16 11:59:31 -0700352 }
353
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800354 /**
355 * Group Instruction.
sangho8995ac52015-02-04 11:29:03 -0800356 */
sangho8995ac52015-02-04 11:29:03 -0800357 public static final class GroupInstruction implements Instruction {
358 private final GroupId groupId;
359
360 private GroupInstruction(GroupId groupId) {
361 this.groupId = groupId;
362 }
363
364 public GroupId groupId() {
365 return groupId;
366 }
367
368 @Override
369 public Type type() {
370 return Type.GROUP;
371 }
alshabib9af70072015-02-09 14:34:16 -0800372
sangho8995ac52015-02-04 11:29:03 -0800373 @Override
374 public String toString() {
375 return toStringHelper(type().toString())
376 .add("group ID", groupId.id()).toString();
377 }
378
379 @Override
380 public int hashCode() {
381 return Objects.hash(type(), groupId);
382 }
383
384 @Override
385 public boolean equals(Object obj) {
386 if (this == obj) {
387 return true;
388 }
389 if (obj instanceof GroupInstruction) {
390 GroupInstruction that = (GroupInstruction) obj;
391 return Objects.equals(groupId, that.groupId);
392
393 }
394 return false;
395 }
396 }
397
alshabib9af70072015-02-09 14:34:16 -0800398 // FIXME: Temporary support for this. This should probably become it's own
399 // type like other instructions.
400 public static class TableTypeTransition implements Instruction {
401 private final FlowRule.Type tableType;
402
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800403 TableTypeTransition(FlowRule.Type type) {
alshabib9af70072015-02-09 14:34:16 -0800404 this.tableType = type;
405 }
406
407 @Override
408 public Type type() {
409 return Type.TABLE;
410 }
411
412 public FlowRule.Type tableType() {
413 return this.tableType;
414 }
415
416 @Override
417 public String toString() {
418 return toStringHelper(type().toString())
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800419 .add("tableType", this.tableType).toString();
alshabib9af70072015-02-09 14:34:16 -0800420 }
421
422 @Override
423 public int hashCode() {
424 return Objects.hash(type(), tableType);
425 }
426
427 @Override
428 public boolean equals(Object obj) {
429 if (this == obj) {
430 return true;
431 }
432 if (obj instanceof TableTypeTransition) {
433 TableTypeTransition that = (TableTypeTransition) obj;
434 return Objects.equals(tableType, that.tableType);
435
436 }
437 return false;
438 }
439
440 }
alshabib55a55d92014-09-16 11:59:31 -0700441}
alshabib8ca53902014-10-07 13:11:17 -0700442
443