blob: ac93f7be54253d0b4a8fcae74946577e9eb4e1f9 [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;
Brian O'Connorabafb502014-12-02 22:26:20 -080029import org.onosproject.net.flow.instructions.L0ModificationInstruction;
30import org.onosproject.net.flow.instructions.L0ModificationInstruction.ModLambdaInstruction;
Sho SHIMIZUe397ffe2015-05-12 16:24:23 -070031import org.onosproject.net.flow.instructions.L0ModificationInstruction.ModOchSignalInstruction;
Brian O'Connorabafb502014-12-02 22:26:20 -080032import org.onosproject.net.flow.instructions.L2ModificationInstruction;
33import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
Saurav Das73a7dd42015-08-19 22:20:31 -070034import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsBosInstruction;
Jonathan Hart29afca32015-01-20 18:17:39 -080035import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsLabelInstruction;
Brian O'Connorabafb502014-12-02 22:26:20 -080036import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
37import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction;
Brian O'Connorabafb502014-12-02 22:26:20 -080038import org.onosproject.net.flow.instructions.L2ModificationInstruction.PushHeaderInstructions;
Hyunsun Moona08c5d02015-07-14 17:53:00 -070039import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModTunnelIdInstruction;
Brian O'Connorabafb502014-12-02 22:26:20 -080040import org.onosproject.net.flow.instructions.L3ModificationInstruction;
41import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -080042import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPv6FlowLabelInstruction;
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -070043import org.onosproject.net.flow.instructions.L4ModificationInstruction;
44import org.onosproject.net.flow.instructions.L4ModificationInstruction.ModTransportPortInstruction;
Jonathan Hart86e59352014-10-22 10:42:16 -070045import org.projectfloodlight.openflow.protocol.OFFactory;
46import org.projectfloodlight.openflow.protocol.OFFlowAdd;
47import org.projectfloodlight.openflow.protocol.OFFlowDelete;
48import org.projectfloodlight.openflow.protocol.OFFlowMod;
49import org.projectfloodlight.openflow.protocol.OFFlowModFlags;
50import org.projectfloodlight.openflow.protocol.action.OFAction;
sangho8995ac52015-02-04 11:29:03 -080051import org.projectfloodlight.openflow.protocol.action.OFActionGroup;
Charles M.C. Chanfe421812015-01-12 18:20:51 +080052import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
alshabib9af70072015-02-09 14:34:16 -080053import org.projectfloodlight.openflow.protocol.instruction.OFInstruction;
Jonathan Hart86e59352014-10-22 10:42:16 -070054import org.projectfloodlight.openflow.protocol.match.Match;
55import org.projectfloodlight.openflow.protocol.oxm.OFOxm;
56import org.projectfloodlight.openflow.types.CircuitSignalID;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -080057import org.projectfloodlight.openflow.types.EthType;
Jonathan Hart86e59352014-10-22 10:42:16 -070058import org.projectfloodlight.openflow.types.IPv4Address;
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -080059import org.projectfloodlight.openflow.types.IPv6Address;
60import org.projectfloodlight.openflow.types.IPv6FlowLabel;
Jonathan Hart86e59352014-10-22 10:42:16 -070061import org.projectfloodlight.openflow.types.MacAddress;
Saurav Das73a7dd42015-08-19 22:20:31 -070062import org.projectfloodlight.openflow.types.OFBooleanValue;
Jonathan Hart86e59352014-10-22 10:42:16 -070063import org.projectfloodlight.openflow.types.OFBufferId;
sangho8995ac52015-02-04 11:29:03 -080064import org.projectfloodlight.openflow.types.OFGroup;
Jonathan Hart86e59352014-10-22 10:42:16 -070065import org.projectfloodlight.openflow.types.OFPort;
66import org.projectfloodlight.openflow.types.OFVlanVidMatch;
alshabib9af70072015-02-09 14:34:16 -080067import org.projectfloodlight.openflow.types.TableId;
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -070068import org.projectfloodlight.openflow.types.TransportPort;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -080069import org.projectfloodlight.openflow.types.U32;
Jonathan Hart86e59352014-10-22 10:42:16 -070070import org.projectfloodlight.openflow.types.U64;
71import org.projectfloodlight.openflow.types.VlanPcp;
72import org.slf4j.Logger;
73import org.slf4j.LoggerFactory;
74
Jonathan Hart29afca32015-01-20 18:17:39 -080075import java.util.Collections;
76import java.util.LinkedList;
77import java.util.List;
78import java.util.Optional;
79
Jonathan Hart86e59352014-10-22 10:42:16 -070080/**
81 * Flow mod builder for OpenFlow 1.3+.
82 */
83public class FlowModBuilderVer13 extends FlowModBuilder {
84
alshabib10580802015-02-18 18:30:33 -080085 private final Logger log = LoggerFactory.getLogger(getClass());
Charles M.C. Chanfe421812015-01-12 18:20:51 +080086 private static final int OFPCML_NO_BUFFER = 0xffff;
Jonathan Hart86e59352014-10-22 10:42:16 -070087
88 private final TrafficTreatment treatment;
89
90 /**
91 * Constructor for a flow mod builder for OpenFlow 1.3.
92 *
93 * @param flowRule the flow rule to transform into a flow mod
94 * @param factory the OpenFlow factory to use to build the flow mod
Pavlin Radoslavov119fd5c2014-11-25 19:08:19 -080095 * @param xid the transaction ID
Jonathan Hart86e59352014-10-22 10:42:16 -070096 */
Brian O'Connor427a1762014-11-19 18:40:32 -080097 protected FlowModBuilderVer13(FlowRule flowRule, OFFactory factory, Optional<Long> xid) {
98 super(flowRule, factory, xid);
Jonathan Hart86e59352014-10-22 10:42:16 -070099
100 this.treatment = flowRule.treatment();
101 }
102
103 @Override
104 public OFFlowAdd buildFlowAdd() {
105 Match match = buildMatch();
alshabib346b5b32015-03-06 00:42:16 -0800106 List<OFAction> deferredActions = buildActions(treatment.deferred());
107 List<OFAction> immediateActions = buildActions(treatment.immediate());
108 List<OFInstruction> instructions = Lists.newLinkedList();
Saurav Dascbe6de32015-03-01 18:30:46 -0800109
Jonathan Hartd4a8bba2014-10-28 12:44:20 -0700110
alshabib346b5b32015-03-06 00:42:16 -0800111 if (treatment.clearedDeferred()) {
112 instructions.add(factory().instructions().clearActions());
113 }
sangho1e575652015-05-14 00:39:53 -0700114 if (immediateActions.size() > 0) {
115 instructions.add(factory().instructions().applyActions(immediateActions));
116 }
alshabib346b5b32015-03-06 00:42:16 -0800117 if (deferredActions.size() > 0) {
118 instructions.add(factory().instructions().writeActions(deferredActions));
119 }
120 if (treatment.tableTransition() != null) {
121 instructions.add(buildTableGoto(treatment.tableTransition()));
Saurav Dascbe6de32015-03-01 18:30:46 -0800122 }
Saurav Das86af8f12015-05-25 23:55:33 -0700123 if (treatment.writeMetadata() != null) {
124 instructions.add(buildMetadata(treatment.writeMetadata()));
125 }
Jonathan Hart86e59352014-10-22 10:42:16 -0700126
127 long cookie = flowRule().id().value();
128
Jonathan Hart86e59352014-10-22 10:42:16 -0700129 OFFlowAdd fm = factory().buildFlowAdd()
Brian O'Connor427a1762014-11-19 18:40:32 -0800130 .setXid(xid)
Jonathan Hart86e59352014-10-22 10:42:16 -0700131 .setCookie(U64.of(cookie))
132 .setBufferId(OFBufferId.NO_BUFFER)
alshabib9af70072015-02-09 14:34:16 -0800133 .setInstructions(instructions)
Jonathan Hart86e59352014-10-22 10:42:16 -0700134 .setMatch(match)
135 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
136 .setPriority(flowRule().priority())
alshabib08d98982015-04-21 16:25:50 -0700137 .setTableId(TableId.of(flowRule().tableId()))
Jonathan Hart86e59352014-10-22 10:42:16 -0700138 .build();
139
140 return fm;
141 }
142
143 @Override
144 public OFFlowMod buildFlowMod() {
145 Match match = buildMatch();
alshabib346b5b32015-03-06 00:42:16 -0800146 List<OFAction> deferredActions = buildActions(treatment.deferred());
147 List<OFAction> immediateActions = buildActions(treatment.immediate());
148 List<OFInstruction> instructions = Lists.newLinkedList();
Jonathan Harteda33872015-02-18 10:22:32 -0800149
alshabib346b5b32015-03-06 00:42:16 -0800150
151 if (immediateActions.size() > 0) {
152 instructions.add(factory().instructions().applyActions(immediateActions));
153 }
154 if (treatment.clearedDeferred()) {
155 instructions.add(factory().instructions().clearActions());
156 }
157 if (deferredActions.size() > 0) {
158 instructions.add(factory().instructions().writeActions(deferredActions));
159 }
160 if (treatment.tableTransition() != null) {
161 instructions.add(buildTableGoto(treatment.tableTransition()));
Saurav Dascbe6de32015-03-01 18:30:46 -0800162 }
Saurav Das86af8f12015-05-25 23:55:33 -0700163 if (treatment.writeMetadata() != null) {
164 instructions.add(buildMetadata(treatment.writeMetadata()));
165 }
alshabib10c810b2015-08-18 16:59:04 -0700166 if (treatment.metered() != null) {
167 instructions.add(buildMeter(treatment.metered()));
168 }
Jonathan Hart86e59352014-10-22 10:42:16 -0700169
170 long cookie = flowRule().id().value();
171
Jonathan Hart86e59352014-10-22 10:42:16 -0700172 OFFlowMod fm = factory().buildFlowModify()
Brian O'Connor427a1762014-11-19 18:40:32 -0800173 .setXid(xid)
Jonathan Hart86e59352014-10-22 10:42:16 -0700174 .setCookie(U64.of(cookie))
175 .setBufferId(OFBufferId.NO_BUFFER)
alshabib9af70072015-02-09 14:34:16 -0800176 .setInstructions(instructions)
Jonathan Hart86e59352014-10-22 10:42:16 -0700177 .setMatch(match)
178 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
179 .setPriority(flowRule().priority())
alshabib08d98982015-04-21 16:25:50 -0700180 .setTableId(TableId.of(flowRule().tableId()))
Jonathan Hart86e59352014-10-22 10:42:16 -0700181 .build();
182
183 return fm;
184 }
185
186 @Override
187 public OFFlowDelete buildFlowDel() {
188 Match match = buildMatch();
Jonathan Hart86e59352014-10-22 10:42:16 -0700189
190 long cookie = flowRule().id().value();
191
192 OFFlowDelete fm = factory().buildFlowDelete()
Brian O'Connor427a1762014-11-19 18:40:32 -0800193 .setXid(xid)
Jonathan Hart86e59352014-10-22 10:42:16 -0700194 .setCookie(U64.of(cookie))
195 .setBufferId(OFBufferId.NO_BUFFER)
Jonathan Hart86e59352014-10-22 10:42:16 -0700196 .setMatch(match)
197 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
198 .setPriority(flowRule().priority())
alshabib08d98982015-04-21 16:25:50 -0700199 .setTableId(TableId.of(flowRule().tableId()))
Jonathan Hart86e59352014-10-22 10:42:16 -0700200 .build();
201
202 return fm;
203 }
204
alshabib346b5b32015-03-06 00:42:16 -0800205 private List<OFAction> buildActions(List<Instruction> treatments) {
Jonathan Hart86e59352014-10-22 10:42:16 -0700206 if (treatment == null) {
Sho SHIMIZU6601dd72015-05-11 19:00:29 -0700207 return Collections.emptyList();
Jonathan Hart86e59352014-10-22 10:42:16 -0700208 }
Sho SHIMIZU6601dd72015-05-11 19:00:29 -0700209
210 boolean tableFound = false;
211 List<OFAction> actions = new LinkedList<>();
alshabib346b5b32015-03-06 00:42:16 -0800212 for (Instruction i : treatments) {
Jonathan Hart86e59352014-10-22 10:42:16 -0700213 switch (i.type()) {
alshabib9af70072015-02-09 14:34:16 -0800214 case DROP:
Sho SHIMIZUb35ed362015-04-28 11:05:19 -0700215 return Collections.emptyList();
alshabib9af70072015-02-09 14:34:16 -0800216 case L0MODIFICATION:
217 actions.add(buildL0Modification(i));
218 break;
219 case L2MODIFICATION:
220 actions.add(buildL2Modification(i));
221 break;
222 case L3MODIFICATION:
223 actions.add(buildL3Modification(i));
224 break;
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -0700225 case L4MODIFICATION:
226 actions.add(buildL4Modification(i));
227 break;
alshabib9af70072015-02-09 14:34:16 -0800228 case OUTPUT:
229 OutputInstruction out = (OutputInstruction) i;
230 OFActionOutput.Builder action = factory().actions().buildOutput()
231 .setPort(OFPort.of((int) out.port().toLong()));
232 if (out.port().equals(PortNumber.CONTROLLER)) {
233 action.setMaxLen(OFPCML_NO_BUFFER);
234 }
235 actions.add(action.build());
236 break;
237 case GROUP:
238 GroupInstruction group = (GroupInstruction) i;
239 OFActionGroup.Builder groupBuilder = factory().actions().buildGroup()
240 .setGroup(OFGroup.of(group.groupId().id()));
241 actions.add(groupBuilder.build());
242 break;
alshabib10580802015-02-18 18:30:33 -0800243 case TABLE:
244 //FIXME: should not occur here.
Saurav Dascbe6de32015-03-01 18:30:46 -0800245 tableFound = true;
alshabib10580802015-02-18 18:30:33 -0800246 break;
alshabib9af70072015-02-09 14:34:16 -0800247 default:
248 log.warn("Instruction type {} not yet implemented.", i.type());
Jonathan Hart86e59352014-10-22 10:42:16 -0700249 }
250 }
Saurav Dascbe6de32015-03-01 18:30:46 -0800251 if (tableFound && actions.isEmpty()) {
252 // handles the case where there are no actions, but there is
253 // a goto instruction for the next table
Sho SHIMIZU6601dd72015-05-11 19:00:29 -0700254 return Collections.emptyList();
Saurav Dascbe6de32015-03-01 18:30:46 -0800255 }
Jonathan Hart86e59352014-10-22 10:42:16 -0700256 return actions;
257 }
258
alshabib9af70072015-02-09 14:34:16 -0800259 private OFInstruction buildTableGoto(Instructions.TableTypeTransition i) {
260 OFInstruction instruction = factory().instructions().gotoTable(
alshabibd17abc22015-04-21 18:26:35 -0700261 TableId.of(i.tableId()));
alshabib9af70072015-02-09 14:34:16 -0800262 return instruction;
263 }
264
Saurav Das86af8f12015-05-25 23:55:33 -0700265 private OFInstruction buildMetadata(Instructions.MetadataInstruction m) {
266 OFInstruction instruction = factory().instructions().writeMetadata(
267 U64.of(m.metadata()), U64.of(m.metadataMask()));
268 return instruction;
269 }
270
alshabib10c810b2015-08-18 16:59:04 -0700271 private OFInstruction buildMeter(Instructions.MeterInstruction metered) {
272 return factory().instructions().meter(metered.meterId().id());
273 }
274
275
Jonathan Hart86e59352014-10-22 10:42:16 -0700276 private OFAction buildL0Modification(Instruction i) {
277 L0ModificationInstruction l0m = (L0ModificationInstruction) i;
278 switch (l0m.subtype()) {
Sho SHIMIZU5cd7ce92015-05-11 19:10:38 -0700279 case LAMBDA:
Sho SHIMIZUe397ffe2015-05-12 16:24:23 -0700280 return buildModLambdaInstruction((ModLambdaInstruction) i);
281 case OCH:
282 try {
283 return buildModOchSignalInstruction((ModOchSignalInstruction) i);
Sho SHIMIZUc17042d2015-05-28 12:07:23 -0700284 } catch (NoMappingFoundException e) {
Sho SHIMIZUe397ffe2015-05-12 16:24:23 -0700285 log.warn(e.getMessage());
286 break;
287 }
Sho SHIMIZU5cd7ce92015-05-11 19:10:38 -0700288 default:
289 log.warn("Unimplemented action type {}.", l0m.subtype());
290 break;
Jonathan Hart86e59352014-10-22 10:42:16 -0700291 }
292 return null;
293 }
294
Sho SHIMIZUe397ffe2015-05-12 16:24:23 -0700295 private OFAction buildModLambdaInstruction(ModLambdaInstruction instruction) {
296 return factory().actions().circuit(factory().oxms().ochSigidBasic(
297 new CircuitSignalID((byte) 1, (byte) 2, instruction.lambda(), (short) 1)));
298 }
299
300 private OFAction buildModOchSignalInstruction(ModOchSignalInstruction instruction) {
301 OchSignal signal = instruction.lambda();
Sho SHIMIZUc17042d2015-05-28 12:07:23 -0700302 byte gridType = OpenFlowValueMapper.lookupGridType(signal.gridType());
303 byte channelSpacing = OpenFlowValueMapper.lookupChannelSpacing(signal.channelSpacing());
Sho SHIMIZUe397ffe2015-05-12 16:24:23 -0700304
305 return factory().actions().circuit(factory().oxms().ochSigidBasic(
306 new CircuitSignalID(gridType, channelSpacing,
307 (short) signal.spacingMultiplier(), (short) signal.slotGranularity())
308 ));
309 }
310
Jonathan Hart86e59352014-10-22 10:42:16 -0700311 private OFAction buildL2Modification(Instruction i) {
312 L2ModificationInstruction l2m = (L2ModificationInstruction) i;
313 ModEtherInstruction eth;
314 OFOxm<?> oxm = null;
315 switch (l2m.subtype()) {
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800316 case ETH_DST:
317 eth = (ModEtherInstruction) l2m;
318 oxm = factory().oxms().ethDst(MacAddress.of(eth.mac().toLong()));
319 break;
320 case ETH_SRC:
321 eth = (ModEtherInstruction) l2m;
322 oxm = factory().oxms().ethSrc(MacAddress.of(eth.mac().toLong()));
323 break;
324 case VLAN_ID:
325 ModVlanIdInstruction vlanId = (ModVlanIdInstruction) l2m;
326 oxm = factory().oxms().vlanVid(OFVlanVidMatch.ofVlan(vlanId.vlanId().toShort()));
327 break;
328 case VLAN_PCP:
329 ModVlanPcpInstruction vlanPcp = (ModVlanPcpInstruction) l2m;
330 oxm = factory().oxms().vlanPcp(VlanPcp.of(vlanPcp.vlanPcp()));
331 break;
332 case MPLS_PUSH:
333 PushHeaderInstructions pushHeaderInstructions =
334 (PushHeaderInstructions) l2m;
335 return factory().actions().pushMpls(EthType.of(pushHeaderInstructions
alshabib7b808c52015-06-26 14:22:24 -0700336 .ethernetType().toShort()));
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800337 case MPLS_POP:
Jonathan Hart67fc0972015-03-19 15:21:20 -0700338 PushHeaderInstructions popHeaderInstructions =
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800339 (PushHeaderInstructions) l2m;
340 return factory().actions().popMpls(EthType.of(popHeaderInstructions
alshabib7b808c52015-06-26 14:22:24 -0700341 .ethernetType().toShort()));
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800342 case MPLS_LABEL:
343 ModMplsLabelInstruction mplsLabel =
344 (ModMplsLabelInstruction) l2m;
345 oxm = factory().oxms().mplsLabel(U32.of(mplsLabel.label()
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -0700346 .longValue()));
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800347 break;
Saurav Das73a7dd42015-08-19 22:20:31 -0700348 case MPLS_BOS:
349 ModMplsBosInstruction mplsBos = (ModMplsBosInstruction) l2m;
350 oxm = factory().oxms()
351 .mplsBos(mplsBos.mplsBos() ? OFBooleanValue.TRUE
352 : OFBooleanValue.FALSE);
353 break;
sangho3f97a17d2015-01-29 22:56:29 -0800354 case DEC_MPLS_TTL:
355 return factory().actions().decMplsTtl();
Saurav Dasfbe25c52015-03-04 11:12:00 -0800356 case VLAN_POP:
357 return factory().actions().popVlan();
Jonathan Hart54b406b2015-03-06 16:24:14 -0800358 case VLAN_PUSH:
359 PushHeaderInstructions pushVlanInstruction = (PushHeaderInstructions) l2m;
360 return factory().actions().pushVlan(
alshabib7b808c52015-06-26 14:22:24 -0700361 EthType.of(pushVlanInstruction.ethernetType().toShort()));
Hyunsun Moona08c5d02015-07-14 17:53:00 -0700362 case TUNNEL_ID:
363 ModTunnelIdInstruction tunnelId = (ModTunnelIdInstruction) l2m;
364 oxm = factory().oxms().tunnelId(U64.of(tunnelId.tunnelId()));
365 break;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800366 default:
367 log.warn("Unimplemented action type {}.", l2m.subtype());
368 break;
Jonathan Hart86e59352014-10-22 10:42:16 -0700369 }
370
371 if (oxm != null) {
372 return factory().actions().buildSetField().setField(oxm).build();
373 }
374 return null;
375 }
376
377 private OFAction buildL3Modification(Instruction i) {
378 L3ModificationInstruction l3m = (L3ModificationInstruction) i;
379 ModIPInstruction ip;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800380 Ip4Address ip4;
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800381 Ip6Address ip6;
Jonathan Hart86e59352014-10-22 10:42:16 -0700382 OFOxm<?> oxm = null;
383 switch (l3m.subtype()) {
Sho SHIMIZU5cd7ce92015-05-11 19:10:38 -0700384 case IPV4_SRC:
385 ip = (ModIPInstruction) i;
386 ip4 = ip.ip().getIp4Address();
387 oxm = factory().oxms().ipv4Src(IPv4Address.of(ip4.toInt()));
388 break;
389 case IPV4_DST:
390 ip = (ModIPInstruction) i;
391 ip4 = ip.ip().getIp4Address();
392 oxm = factory().oxms().ipv4Dst(IPv4Address.of(ip4.toInt()));
393 break;
394 case IPV6_SRC:
395 ip = (ModIPInstruction) i;
396 ip6 = ip.ip().getIp6Address();
397 oxm = factory().oxms().ipv6Src(IPv6Address.of(ip6.toOctets()));
398 break;
399 case IPV6_DST:
400 ip = (ModIPInstruction) i;
401 ip6 = ip.ip().getIp6Address();
402 oxm = factory().oxms().ipv6Dst(IPv6Address.of(ip6.toOctets()));
403 break;
404 case IPV6_FLABEL:
405 ModIPv6FlowLabelInstruction flowLabelInstruction =
406 (ModIPv6FlowLabelInstruction) i;
407 int flowLabel = flowLabelInstruction.flowLabel();
408 oxm = factory().oxms().ipv6Flabel(IPv6FlowLabel.of(flowLabel));
409 break;
410 case DEC_TTL:
411 return factory().actions().decNwTtl();
412 case TTL_IN:
413 return factory().actions().copyTtlIn();
414 case TTL_OUT:
415 return factory().actions().copyTtlOut();
416 default:
417 log.warn("Unimplemented action type {}.", l3m.subtype());
418 break;
Jonathan Hart86e59352014-10-22 10:42:16 -0700419 }
420
421 if (oxm != null) {
422 return factory().actions().buildSetField().setField(oxm).build();
423 }
424 return null;
425 }
426
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -0700427 private OFAction buildL4Modification(Instruction i) {
428 L4ModificationInstruction l4m = (L4ModificationInstruction) i;
429 ModTransportPortInstruction tp;
430 OFOxm<?> oxm = null;
431 switch (l4m.subtype()) {
432 case TCP_SRC:
433 tp = (ModTransportPortInstruction) l4m;
434 oxm = factory().oxms().tcpSrc(TransportPort.of(tp.port()));
435 break;
436 case TCP_DST:
437 tp = (ModTransportPortInstruction) l4m;
438 oxm = factory().oxms().tcpDst(TransportPort.of(tp.port()));
439 break;
440 case UDP_SRC:
441 tp = (ModTransportPortInstruction) l4m;
442 oxm = factory().oxms().udpSrc(TransportPort.of(tp.port()));
443 break;
444 case UDP_DST:
445 tp = (ModTransportPortInstruction) l4m;
446 oxm = factory().oxms().udpDst(TransportPort.of(tp.port()));
447 break;
448 default:
449 log.warn("Unimplemented action type {}.", l4m.subtype());
450 break;
451 }
452
453 if (oxm != null) {
454 return factory().actions().buildSetField().setField(oxm).build();
455 }
456 return null;
457 }
458
Jonathan Hart86e59352014-10-22 10:42:16 -0700459}