blob: 64b4360a04aee461a5bba09a04abba118893e68a [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Ray Milkey34c95902015-04-15 09:47:53 -07002 * Copyright 2014-2015 Open Networking Laboratory
Thomas Vachuska781d18b2014-10-27 10:31:25 -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 Vachuska781d18b2014-10-27 10:31:25 -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 Vachuska781d18b2014-10-27 10:31:25 -070015 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.provider.of.flow.impl;
Jonathan Hart86e59352014-10-22 10:42:16 -070017
alshabib346b5b32015-03-06 00:42:16 -080018import com.google.common.collect.Lists;
Jonathan Hart29afca32015-01-20 18:17:39 -080019import org.onlab.packet.Ip4Address;
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -080020import org.onlab.packet.Ip6Address;
Sho SHIMIZUe397ffe2015-05-12 16:24:23 -070021import org.onosproject.net.OchSignal;
Charles M.C. Chanfe421812015-01-12 18:20:51 +080022import org.onosproject.net.PortNumber;
Brian O'Connorabafb502014-12-02 22:26:20 -080023import org.onosproject.net.flow.FlowRule;
24import org.onosproject.net.flow.TrafficTreatment;
25import org.onosproject.net.flow.instructions.Instruction;
alshabib9af70072015-02-09 14:34:16 -080026import org.onosproject.net.flow.instructions.Instructions;
sangho8995ac52015-02-04 11:29:03 -080027import org.onosproject.net.flow.instructions.Instructions.GroupInstruction;
alshabib9af70072015-02-09 14:34:16 -080028import org.onosproject.net.flow.instructions.Instructions.OutputInstruction;
Steffen Gebertbbfdaaa2015-09-29 11:01:46 +020029import org.onosproject.net.flow.instructions.Instructions.SetQueueInstruction;
Brian O'Connorabafb502014-12-02 22:26:20 -080030import org.onosproject.net.flow.instructions.L0ModificationInstruction;
31import org.onosproject.net.flow.instructions.L0ModificationInstruction.ModLambdaInstruction;
Sho SHIMIZUe397ffe2015-05-12 16:24:23 -070032import org.onosproject.net.flow.instructions.L0ModificationInstruction.ModOchSignalInstruction;
Brian O'Connorabafb502014-12-02 22:26:20 -080033import org.onosproject.net.flow.instructions.L2ModificationInstruction;
34import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
Saurav Das73a7dd42015-08-19 22:20:31 -070035import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsBosInstruction;
Jonathan Hart29afca32015-01-20 18:17:39 -080036import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsLabelInstruction;
Brian O'Connorabafb502014-12-02 22:26:20 -080037import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
38import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction;
Brian O'Connorabafb502014-12-02 22:26:20 -080039import org.onosproject.net.flow.instructions.L2ModificationInstruction.PushHeaderInstructions;
Hyunsun Moona08c5d02015-07-14 17:53:00 -070040import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModTunnelIdInstruction;
Brian O'Connorabafb502014-12-02 22:26:20 -080041import org.onosproject.net.flow.instructions.L3ModificationInstruction;
42import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -080043import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPv6FlowLabelInstruction;
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -070044import org.onosproject.net.flow.instructions.L4ModificationInstruction;
45import org.onosproject.net.flow.instructions.L4ModificationInstruction.ModTransportPortInstruction;
Jonathan Hart86e59352014-10-22 10:42:16 -070046import org.projectfloodlight.openflow.protocol.OFFactory;
47import org.projectfloodlight.openflow.protocol.OFFlowAdd;
48import org.projectfloodlight.openflow.protocol.OFFlowDelete;
49import org.projectfloodlight.openflow.protocol.OFFlowMod;
50import org.projectfloodlight.openflow.protocol.OFFlowModFlags;
51import org.projectfloodlight.openflow.protocol.action.OFAction;
sangho8995ac52015-02-04 11:29:03 -080052import org.projectfloodlight.openflow.protocol.action.OFActionGroup;
Charles M.C. Chanfe421812015-01-12 18:20:51 +080053import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
Steffen Gebertbbfdaaa2015-09-29 11:01:46 +020054import org.projectfloodlight.openflow.protocol.action.OFActionSetQueue;
alshabib9af70072015-02-09 14:34:16 -080055import org.projectfloodlight.openflow.protocol.instruction.OFInstruction;
Jonathan Hart86e59352014-10-22 10:42:16 -070056import org.projectfloodlight.openflow.protocol.match.Match;
57import org.projectfloodlight.openflow.protocol.oxm.OFOxm;
58import org.projectfloodlight.openflow.types.CircuitSignalID;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -080059import org.projectfloodlight.openflow.types.EthType;
Jonathan Hart86e59352014-10-22 10:42:16 -070060import org.projectfloodlight.openflow.types.IPv4Address;
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -080061import org.projectfloodlight.openflow.types.IPv6Address;
62import org.projectfloodlight.openflow.types.IPv6FlowLabel;
Jonathan Hart86e59352014-10-22 10:42:16 -070063import org.projectfloodlight.openflow.types.MacAddress;
Saurav Das73a7dd42015-08-19 22:20:31 -070064import org.projectfloodlight.openflow.types.OFBooleanValue;
Jonathan Hart86e59352014-10-22 10:42:16 -070065import org.projectfloodlight.openflow.types.OFBufferId;
sangho8995ac52015-02-04 11:29:03 -080066import org.projectfloodlight.openflow.types.OFGroup;
Jonathan Hart86e59352014-10-22 10:42:16 -070067import org.projectfloodlight.openflow.types.OFPort;
68import org.projectfloodlight.openflow.types.OFVlanVidMatch;
alshabib9af70072015-02-09 14:34:16 -080069import org.projectfloodlight.openflow.types.TableId;
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -070070import org.projectfloodlight.openflow.types.TransportPort;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -080071import org.projectfloodlight.openflow.types.U32;
Jonathan Hart86e59352014-10-22 10:42:16 -070072import org.projectfloodlight.openflow.types.U64;
73import org.projectfloodlight.openflow.types.VlanPcp;
74import org.slf4j.Logger;
75import org.slf4j.LoggerFactory;
76
Jonathan Hart29afca32015-01-20 18:17:39 -080077import java.util.Collections;
78import java.util.LinkedList;
79import java.util.List;
80import java.util.Optional;
81
Jonathan Hart86e59352014-10-22 10:42:16 -070082/**
83 * Flow mod builder for OpenFlow 1.3+.
84 */
85public class FlowModBuilderVer13 extends FlowModBuilder {
86
alshabib10580802015-02-18 18:30:33 -080087 private final Logger log = LoggerFactory.getLogger(getClass());
Charles M.C. Chanfe421812015-01-12 18:20:51 +080088 private static final int OFPCML_NO_BUFFER = 0xffff;
Jonathan Hart86e59352014-10-22 10:42:16 -070089
90 private final TrafficTreatment treatment;
91
92 /**
93 * Constructor for a flow mod builder for OpenFlow 1.3.
94 *
95 * @param flowRule the flow rule to transform into a flow mod
96 * @param factory the OpenFlow factory to use to build the flow mod
Pavlin Radoslavov119fd5c2014-11-25 19:08:19 -080097 * @param xid the transaction ID
Jonathan Hart86e59352014-10-22 10:42:16 -070098 */
Brian O'Connor427a1762014-11-19 18:40:32 -080099 protected FlowModBuilderVer13(FlowRule flowRule, OFFactory factory, Optional<Long> xid) {
100 super(flowRule, factory, xid);
Jonathan Hart86e59352014-10-22 10:42:16 -0700101
102 this.treatment = flowRule.treatment();
103 }
104
105 @Override
106 public OFFlowAdd buildFlowAdd() {
107 Match match = buildMatch();
alshabib346b5b32015-03-06 00:42:16 -0800108 List<OFAction> deferredActions = buildActions(treatment.deferred());
109 List<OFAction> immediateActions = buildActions(treatment.immediate());
110 List<OFInstruction> instructions = Lists.newLinkedList();
Saurav Dascbe6de32015-03-01 18:30:46 -0800111
Jonathan Hartd4a8bba2014-10-28 12:44:20 -0700112
alshabib346b5b32015-03-06 00:42:16 -0800113 if (treatment.clearedDeferred()) {
114 instructions.add(factory().instructions().clearActions());
115 }
sangho1e575652015-05-14 00:39:53 -0700116 if (immediateActions.size() > 0) {
117 instructions.add(factory().instructions().applyActions(immediateActions));
118 }
alshabib346b5b32015-03-06 00:42:16 -0800119 if (deferredActions.size() > 0) {
120 instructions.add(factory().instructions().writeActions(deferredActions));
121 }
122 if (treatment.tableTransition() != null) {
123 instructions.add(buildTableGoto(treatment.tableTransition()));
Saurav Dascbe6de32015-03-01 18:30:46 -0800124 }
Saurav Das86af8f12015-05-25 23:55:33 -0700125 if (treatment.writeMetadata() != null) {
126 instructions.add(buildMetadata(treatment.writeMetadata()));
127 }
chengfane264bef2015-09-28 08:38:19 +0800128 if (treatment.metered() != null) {
129 instructions.add(buildMeter(treatment.metered()));
130 }
Jonathan Hart86e59352014-10-22 10:42:16 -0700131
132 long cookie = flowRule().id().value();
133
Jonathan Hart86e59352014-10-22 10:42:16 -0700134 OFFlowAdd fm = factory().buildFlowAdd()
Brian O'Connor427a1762014-11-19 18:40:32 -0800135 .setXid(xid)
Jonathan Hart86e59352014-10-22 10:42:16 -0700136 .setCookie(U64.of(cookie))
137 .setBufferId(OFBufferId.NO_BUFFER)
alshabib9af70072015-02-09 14:34:16 -0800138 .setInstructions(instructions)
Jonathan Hart86e59352014-10-22 10:42:16 -0700139 .setMatch(match)
140 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
141 .setPriority(flowRule().priority())
alshabib08d98982015-04-21 16:25:50 -0700142 .setTableId(TableId.of(flowRule().tableId()))
Jonathan Hart86e59352014-10-22 10:42:16 -0700143 .build();
144
145 return fm;
146 }
147
148 @Override
149 public OFFlowMod buildFlowMod() {
150 Match match = buildMatch();
alshabib346b5b32015-03-06 00:42:16 -0800151 List<OFAction> deferredActions = buildActions(treatment.deferred());
152 List<OFAction> immediateActions = buildActions(treatment.immediate());
153 List<OFInstruction> instructions = Lists.newLinkedList();
Jonathan Harteda33872015-02-18 10:22:32 -0800154
alshabib346b5b32015-03-06 00:42:16 -0800155
156 if (immediateActions.size() > 0) {
157 instructions.add(factory().instructions().applyActions(immediateActions));
158 }
159 if (treatment.clearedDeferred()) {
160 instructions.add(factory().instructions().clearActions());
161 }
162 if (deferredActions.size() > 0) {
163 instructions.add(factory().instructions().writeActions(deferredActions));
164 }
165 if (treatment.tableTransition() != null) {
166 instructions.add(buildTableGoto(treatment.tableTransition()));
Saurav Dascbe6de32015-03-01 18:30:46 -0800167 }
Saurav Das86af8f12015-05-25 23:55:33 -0700168 if (treatment.writeMetadata() != null) {
169 instructions.add(buildMetadata(treatment.writeMetadata()));
170 }
alshabib10c810b2015-08-18 16:59:04 -0700171 if (treatment.metered() != null) {
172 instructions.add(buildMeter(treatment.metered()));
173 }
Jonathan Hart86e59352014-10-22 10:42:16 -0700174
175 long cookie = flowRule().id().value();
176
Jonathan Hart86e59352014-10-22 10:42:16 -0700177 OFFlowMod fm = factory().buildFlowModify()
Brian O'Connor427a1762014-11-19 18:40:32 -0800178 .setXid(xid)
Jonathan Hart86e59352014-10-22 10:42:16 -0700179 .setCookie(U64.of(cookie))
180 .setBufferId(OFBufferId.NO_BUFFER)
alshabib9af70072015-02-09 14:34:16 -0800181 .setInstructions(instructions)
Jonathan Hart86e59352014-10-22 10:42:16 -0700182 .setMatch(match)
183 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
184 .setPriority(flowRule().priority())
alshabib08d98982015-04-21 16:25:50 -0700185 .setTableId(TableId.of(flowRule().tableId()))
Jonathan Hart86e59352014-10-22 10:42:16 -0700186 .build();
187
188 return fm;
189 }
190
191 @Override
192 public OFFlowDelete buildFlowDel() {
193 Match match = buildMatch();
Jonathan Hart86e59352014-10-22 10:42:16 -0700194
195 long cookie = flowRule().id().value();
196
197 OFFlowDelete fm = factory().buildFlowDelete()
Brian O'Connor427a1762014-11-19 18:40:32 -0800198 .setXid(xid)
Jonathan Hart86e59352014-10-22 10:42:16 -0700199 .setCookie(U64.of(cookie))
200 .setBufferId(OFBufferId.NO_BUFFER)
Jonathan Hart86e59352014-10-22 10:42:16 -0700201 .setMatch(match)
202 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
203 .setPriority(flowRule().priority())
alshabib08d98982015-04-21 16:25:50 -0700204 .setTableId(TableId.of(flowRule().tableId()))
Jonathan Hart86e59352014-10-22 10:42:16 -0700205 .build();
206
207 return fm;
208 }
209
alshabib346b5b32015-03-06 00:42:16 -0800210 private List<OFAction> buildActions(List<Instruction> treatments) {
Jonathan Hart86e59352014-10-22 10:42:16 -0700211 if (treatment == null) {
Sho SHIMIZU6601dd72015-05-11 19:00:29 -0700212 return Collections.emptyList();
Jonathan Hart86e59352014-10-22 10:42:16 -0700213 }
Sho SHIMIZU6601dd72015-05-11 19:00:29 -0700214
215 boolean tableFound = false;
216 List<OFAction> actions = new LinkedList<>();
alshabib346b5b32015-03-06 00:42:16 -0800217 for (Instruction i : treatments) {
Jonathan Hart86e59352014-10-22 10:42:16 -0700218 switch (i.type()) {
alshabib9af70072015-02-09 14:34:16 -0800219 case DROP:
Charles Chan7efabeb2015-09-28 15:12:19 -0700220 case NOACTION:
Sho SHIMIZUb35ed362015-04-28 11:05:19 -0700221 return Collections.emptyList();
alshabib9af70072015-02-09 14:34:16 -0800222 case L0MODIFICATION:
223 actions.add(buildL0Modification(i));
224 break;
225 case L2MODIFICATION:
226 actions.add(buildL2Modification(i));
227 break;
228 case L3MODIFICATION:
229 actions.add(buildL3Modification(i));
230 break;
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -0700231 case L4MODIFICATION:
232 actions.add(buildL4Modification(i));
233 break;
alshabib9af70072015-02-09 14:34:16 -0800234 case OUTPUT:
235 OutputInstruction out = (OutputInstruction) i;
236 OFActionOutput.Builder action = factory().actions().buildOutput()
237 .setPort(OFPort.of((int) out.port().toLong()));
238 if (out.port().equals(PortNumber.CONTROLLER)) {
239 action.setMaxLen(OFPCML_NO_BUFFER);
240 }
241 actions.add(action.build());
242 break;
243 case GROUP:
244 GroupInstruction group = (GroupInstruction) i;
245 OFActionGroup.Builder groupBuilder = factory().actions().buildGroup()
246 .setGroup(OFGroup.of(group.groupId().id()));
247 actions.add(groupBuilder.build());
248 break;
Steffen Gebertbbfdaaa2015-09-29 11:01:46 +0200249 case QUEUE:
250 SetQueueInstruction queue = (SetQueueInstruction) i;
251 OFActionSetQueue.Builder queueBuilder = factory().actions().buildSetQueue()
252 .setQueueId(queue.queueId());
253 actions.add(queueBuilder.build());
254 break;
alshabib10580802015-02-18 18:30:33 -0800255 case TABLE:
256 //FIXME: should not occur here.
Saurav Dascbe6de32015-03-01 18:30:46 -0800257 tableFound = true;
alshabib10580802015-02-18 18:30:33 -0800258 break;
alshabib9af70072015-02-09 14:34:16 -0800259 default:
260 log.warn("Instruction type {} not yet implemented.", i.type());
Jonathan Hart86e59352014-10-22 10:42:16 -0700261 }
262 }
Saurav Dascbe6de32015-03-01 18:30:46 -0800263 if (tableFound && actions.isEmpty()) {
264 // handles the case where there are no actions, but there is
265 // a goto instruction for the next table
Sho SHIMIZU6601dd72015-05-11 19:00:29 -0700266 return Collections.emptyList();
Saurav Dascbe6de32015-03-01 18:30:46 -0800267 }
Jonathan Hart86e59352014-10-22 10:42:16 -0700268 return actions;
269 }
270
alshabib9af70072015-02-09 14:34:16 -0800271 private OFInstruction buildTableGoto(Instructions.TableTypeTransition i) {
272 OFInstruction instruction = factory().instructions().gotoTable(
alshabibd17abc22015-04-21 18:26:35 -0700273 TableId.of(i.tableId()));
alshabib9af70072015-02-09 14:34:16 -0800274 return instruction;
275 }
276
Saurav Das86af8f12015-05-25 23:55:33 -0700277 private OFInstruction buildMetadata(Instructions.MetadataInstruction m) {
278 OFInstruction instruction = factory().instructions().writeMetadata(
279 U64.of(m.metadata()), U64.of(m.metadataMask()));
280 return instruction;
281 }
282
alshabib10c810b2015-08-18 16:59:04 -0700283 private OFInstruction buildMeter(Instructions.MeterInstruction metered) {
284 return factory().instructions().meter(metered.meterId().id());
285 }
286
287
Jonathan Hart86e59352014-10-22 10:42:16 -0700288 private OFAction buildL0Modification(Instruction i) {
289 L0ModificationInstruction l0m = (L0ModificationInstruction) i;
290 switch (l0m.subtype()) {
Sho SHIMIZU5cd7ce92015-05-11 19:10:38 -0700291 case LAMBDA:
Sho SHIMIZUe397ffe2015-05-12 16:24:23 -0700292 return buildModLambdaInstruction((ModLambdaInstruction) i);
293 case OCH:
294 try {
295 return buildModOchSignalInstruction((ModOchSignalInstruction) i);
Sho SHIMIZUc17042d2015-05-28 12:07:23 -0700296 } catch (NoMappingFoundException e) {
Sho SHIMIZUe397ffe2015-05-12 16:24:23 -0700297 log.warn(e.getMessage());
298 break;
299 }
Sho SHIMIZU5cd7ce92015-05-11 19:10:38 -0700300 default:
301 log.warn("Unimplemented action type {}.", l0m.subtype());
302 break;
Jonathan Hart86e59352014-10-22 10:42:16 -0700303 }
304 return null;
305 }
306
Sho SHIMIZUe397ffe2015-05-12 16:24:23 -0700307 private OFAction buildModLambdaInstruction(ModLambdaInstruction instruction) {
308 return factory().actions().circuit(factory().oxms().ochSigidBasic(
309 new CircuitSignalID((byte) 1, (byte) 2, instruction.lambda(), (short) 1)));
310 }
311
312 private OFAction buildModOchSignalInstruction(ModOchSignalInstruction instruction) {
313 OchSignal signal = instruction.lambda();
Sho SHIMIZUc17042d2015-05-28 12:07:23 -0700314 byte gridType = OpenFlowValueMapper.lookupGridType(signal.gridType());
315 byte channelSpacing = OpenFlowValueMapper.lookupChannelSpacing(signal.channelSpacing());
Sho SHIMIZUe397ffe2015-05-12 16:24:23 -0700316
317 return factory().actions().circuit(factory().oxms().ochSigidBasic(
318 new CircuitSignalID(gridType, channelSpacing,
319 (short) signal.spacingMultiplier(), (short) signal.slotGranularity())
320 ));
321 }
322
Jonathan Hart86e59352014-10-22 10:42:16 -0700323 private OFAction buildL2Modification(Instruction i) {
324 L2ModificationInstruction l2m = (L2ModificationInstruction) i;
325 ModEtherInstruction eth;
326 OFOxm<?> oxm = null;
327 switch (l2m.subtype()) {
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800328 case ETH_DST:
329 eth = (ModEtherInstruction) l2m;
330 oxm = factory().oxms().ethDst(MacAddress.of(eth.mac().toLong()));
331 break;
332 case ETH_SRC:
333 eth = (ModEtherInstruction) l2m;
334 oxm = factory().oxms().ethSrc(MacAddress.of(eth.mac().toLong()));
335 break;
336 case VLAN_ID:
337 ModVlanIdInstruction vlanId = (ModVlanIdInstruction) l2m;
338 oxm = factory().oxms().vlanVid(OFVlanVidMatch.ofVlan(vlanId.vlanId().toShort()));
339 break;
340 case VLAN_PCP:
341 ModVlanPcpInstruction vlanPcp = (ModVlanPcpInstruction) l2m;
342 oxm = factory().oxms().vlanPcp(VlanPcp.of(vlanPcp.vlanPcp()));
343 break;
344 case MPLS_PUSH:
345 PushHeaderInstructions pushHeaderInstructions =
346 (PushHeaderInstructions) l2m;
347 return factory().actions().pushMpls(EthType.of(pushHeaderInstructions
alshabib7b808c52015-06-26 14:22:24 -0700348 .ethernetType().toShort()));
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800349 case MPLS_POP:
Jonathan Hart67fc0972015-03-19 15:21:20 -0700350 PushHeaderInstructions popHeaderInstructions =
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800351 (PushHeaderInstructions) l2m;
352 return factory().actions().popMpls(EthType.of(popHeaderInstructions
alshabib7b808c52015-06-26 14:22:24 -0700353 .ethernetType().toShort()));
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800354 case MPLS_LABEL:
355 ModMplsLabelInstruction mplsLabel =
356 (ModMplsLabelInstruction) l2m;
HIGUCHI Yuta04b49fc2015-08-28 09:58:58 -0700357 oxm = factory().oxms().mplsLabel(U32.of(mplsLabel.mplsLabel().toInt()));
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800358 break;
Saurav Das73a7dd42015-08-19 22:20:31 -0700359 case MPLS_BOS:
360 ModMplsBosInstruction mplsBos = (ModMplsBosInstruction) l2m;
361 oxm = factory().oxms()
362 .mplsBos(mplsBos.mplsBos() ? OFBooleanValue.TRUE
363 : OFBooleanValue.FALSE);
364 break;
sangho3f97a17d2015-01-29 22:56:29 -0800365 case DEC_MPLS_TTL:
366 return factory().actions().decMplsTtl();
Saurav Dasfbe25c52015-03-04 11:12:00 -0800367 case VLAN_POP:
368 return factory().actions().popVlan();
Jonathan Hart54b406b2015-03-06 16:24:14 -0800369 case VLAN_PUSH:
370 PushHeaderInstructions pushVlanInstruction = (PushHeaderInstructions) l2m;
371 return factory().actions().pushVlan(
alshabib7b808c52015-06-26 14:22:24 -0700372 EthType.of(pushVlanInstruction.ethernetType().toShort()));
Hyunsun Moona08c5d02015-07-14 17:53:00 -0700373 case TUNNEL_ID:
374 ModTunnelIdInstruction tunnelId = (ModTunnelIdInstruction) l2m;
375 oxm = factory().oxms().tunnelId(U64.of(tunnelId.tunnelId()));
376 break;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800377 default:
378 log.warn("Unimplemented action type {}.", l2m.subtype());
379 break;
Jonathan Hart86e59352014-10-22 10:42:16 -0700380 }
381
382 if (oxm != null) {
383 return factory().actions().buildSetField().setField(oxm).build();
384 }
385 return null;
386 }
387
388 private OFAction buildL3Modification(Instruction i) {
389 L3ModificationInstruction l3m = (L3ModificationInstruction) i;
390 ModIPInstruction ip;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800391 Ip4Address ip4;
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800392 Ip6Address ip6;
Jonathan Hart86e59352014-10-22 10:42:16 -0700393 OFOxm<?> oxm = null;
394 switch (l3m.subtype()) {
Sho SHIMIZU5cd7ce92015-05-11 19:10:38 -0700395 case IPV4_SRC:
396 ip = (ModIPInstruction) i;
397 ip4 = ip.ip().getIp4Address();
398 oxm = factory().oxms().ipv4Src(IPv4Address.of(ip4.toInt()));
399 break;
400 case IPV4_DST:
401 ip = (ModIPInstruction) i;
402 ip4 = ip.ip().getIp4Address();
403 oxm = factory().oxms().ipv4Dst(IPv4Address.of(ip4.toInt()));
404 break;
405 case IPV6_SRC:
406 ip = (ModIPInstruction) i;
407 ip6 = ip.ip().getIp6Address();
408 oxm = factory().oxms().ipv6Src(IPv6Address.of(ip6.toOctets()));
409 break;
410 case IPV6_DST:
411 ip = (ModIPInstruction) i;
412 ip6 = ip.ip().getIp6Address();
413 oxm = factory().oxms().ipv6Dst(IPv6Address.of(ip6.toOctets()));
414 break;
415 case IPV6_FLABEL:
416 ModIPv6FlowLabelInstruction flowLabelInstruction =
417 (ModIPv6FlowLabelInstruction) i;
418 int flowLabel = flowLabelInstruction.flowLabel();
419 oxm = factory().oxms().ipv6Flabel(IPv6FlowLabel.of(flowLabel));
420 break;
421 case DEC_TTL:
422 return factory().actions().decNwTtl();
423 case TTL_IN:
424 return factory().actions().copyTtlIn();
425 case TTL_OUT:
426 return factory().actions().copyTtlOut();
427 default:
428 log.warn("Unimplemented action type {}.", l3m.subtype());
429 break;
Jonathan Hart86e59352014-10-22 10:42:16 -0700430 }
431
432 if (oxm != null) {
433 return factory().actions().buildSetField().setField(oxm).build();
434 }
435 return null;
436 }
437
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -0700438 private OFAction buildL4Modification(Instruction i) {
439 L4ModificationInstruction l4m = (L4ModificationInstruction) i;
440 ModTransportPortInstruction tp;
441 OFOxm<?> oxm = null;
442 switch (l4m.subtype()) {
443 case TCP_SRC:
444 tp = (ModTransportPortInstruction) l4m;
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700445 oxm = factory().oxms().tcpSrc(TransportPort.of(tp.port().toInt()));
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -0700446 break;
447 case TCP_DST:
448 tp = (ModTransportPortInstruction) l4m;
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700449 oxm = factory().oxms().tcpDst(TransportPort.of(tp.port().toInt()));
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -0700450 break;
451 case UDP_SRC:
452 tp = (ModTransportPortInstruction) l4m;
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700453 oxm = factory().oxms().udpSrc(TransportPort.of(tp.port().toInt()));
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -0700454 break;
455 case UDP_DST:
456 tp = (ModTransportPortInstruction) l4m;
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700457 oxm = factory().oxms().udpDst(TransportPort.of(tp.port().toInt()));
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -0700458 break;
459 default:
460 log.warn("Unimplemented action type {}.", l4m.subtype());
461 break;
462 }
463
464 if (oxm != null) {
465 return factory().actions().buildSetField().setField(oxm).build();
466 }
467 return null;
468 }
469
Jonathan Hart86e59352014-10-22 10:42:16 -0700470}