blob: a99aa8179f16da0935d52b26f06e319def88cd87 [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;
Jonathan Hart3c259162015-10-21 21:31:19 -070021import org.onosproject.net.DeviceId;
Sho SHIMIZUe397ffe2015-05-12 16:24:23 -070022import org.onosproject.net.OchSignal;
Charles M.C. Chanfe421812015-01-12 18:20:51 +080023import org.onosproject.net.PortNumber;
Jonathan Hart3c259162015-10-21 21:31:19 -070024import org.onosproject.net.driver.DefaultDriverData;
25import org.onosproject.net.driver.DefaultDriverHandler;
26import org.onosproject.net.driver.Driver;
27import org.onosproject.net.driver.DriverService;
Brian O'Connorabafb502014-12-02 22:26:20 -080028import org.onosproject.net.flow.FlowRule;
29import org.onosproject.net.flow.TrafficTreatment;
Jonathan Hart3c259162015-10-21 21:31:19 -070030import org.onosproject.net.flow.instructions.ExtensionInstruction;
Brian O'Connorabafb502014-12-02 22:26:20 -080031import org.onosproject.net.flow.instructions.Instruction;
alshabib9af70072015-02-09 14:34:16 -080032import org.onosproject.net.flow.instructions.Instructions;
sangho8995ac52015-02-04 11:29:03 -080033import org.onosproject.net.flow.instructions.Instructions.GroupInstruction;
alshabib9af70072015-02-09 14:34:16 -080034import org.onosproject.net.flow.instructions.Instructions.OutputInstruction;
Steffen Gebertbbfdaaa2015-09-29 11:01:46 +020035import org.onosproject.net.flow.instructions.Instructions.SetQueueInstruction;
Brian O'Connorabafb502014-12-02 22:26:20 -080036import org.onosproject.net.flow.instructions.L0ModificationInstruction;
37import org.onosproject.net.flow.instructions.L0ModificationInstruction.ModLambdaInstruction;
Sho SHIMIZUe397ffe2015-05-12 16:24:23 -070038import org.onosproject.net.flow.instructions.L0ModificationInstruction.ModOchSignalInstruction;
Brian O'Connorabafb502014-12-02 22:26:20 -080039import org.onosproject.net.flow.instructions.L2ModificationInstruction;
40import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
Saurav Das73a7dd42015-08-19 22:20:31 -070041import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsBosInstruction;
Jonathan Hart29afca32015-01-20 18:17:39 -080042import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsLabelInstruction;
Jonathan Hart3c259162015-10-21 21:31:19 -070043import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModTunnelIdInstruction;
Brian O'Connorabafb502014-12-02 22:26:20 -080044import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
45import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction;
Brian O'Connorabafb502014-12-02 22:26:20 -080046import org.onosproject.net.flow.instructions.L2ModificationInstruction.PushHeaderInstructions;
47import org.onosproject.net.flow.instructions.L3ModificationInstruction;
48import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -080049import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPv6FlowLabelInstruction;
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -070050import org.onosproject.net.flow.instructions.L4ModificationInstruction;
51import org.onosproject.net.flow.instructions.L4ModificationInstruction.ModTransportPortInstruction;
Jonathan Hart3c259162015-10-21 21:31:19 -070052import org.onosproject.openflow.controller.ExtensionInterpreter;
Jonathan Hart86e59352014-10-22 10:42:16 -070053import org.projectfloodlight.openflow.protocol.OFFactory;
54import org.projectfloodlight.openflow.protocol.OFFlowAdd;
55import org.projectfloodlight.openflow.protocol.OFFlowDelete;
56import org.projectfloodlight.openflow.protocol.OFFlowMod;
57import org.projectfloodlight.openflow.protocol.OFFlowModFlags;
58import org.projectfloodlight.openflow.protocol.action.OFAction;
sangho8995ac52015-02-04 11:29:03 -080059import org.projectfloodlight.openflow.protocol.action.OFActionGroup;
Charles M.C. Chanfe421812015-01-12 18:20:51 +080060import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
Steffen Gebertbbfdaaa2015-09-29 11:01:46 +020061import org.projectfloodlight.openflow.protocol.action.OFActionSetQueue;
alshabib9af70072015-02-09 14:34:16 -080062import org.projectfloodlight.openflow.protocol.instruction.OFInstruction;
Jonathan Hart86e59352014-10-22 10:42:16 -070063import org.projectfloodlight.openflow.protocol.match.Match;
64import org.projectfloodlight.openflow.protocol.oxm.OFOxm;
65import org.projectfloodlight.openflow.types.CircuitSignalID;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -080066import org.projectfloodlight.openflow.types.EthType;
Jonathan Hart86e59352014-10-22 10:42:16 -070067import org.projectfloodlight.openflow.types.IPv4Address;
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -080068import org.projectfloodlight.openflow.types.IPv6Address;
69import org.projectfloodlight.openflow.types.IPv6FlowLabel;
Jonathan Hart86e59352014-10-22 10:42:16 -070070import org.projectfloodlight.openflow.types.MacAddress;
Saurav Das73a7dd42015-08-19 22:20:31 -070071import org.projectfloodlight.openflow.types.OFBooleanValue;
Jonathan Hart86e59352014-10-22 10:42:16 -070072import org.projectfloodlight.openflow.types.OFBufferId;
sangho8995ac52015-02-04 11:29:03 -080073import org.projectfloodlight.openflow.types.OFGroup;
Jonathan Hart86e59352014-10-22 10:42:16 -070074import org.projectfloodlight.openflow.types.OFPort;
75import org.projectfloodlight.openflow.types.OFVlanVidMatch;
alshabib9af70072015-02-09 14:34:16 -080076import org.projectfloodlight.openflow.types.TableId;
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -070077import org.projectfloodlight.openflow.types.TransportPort;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -080078import org.projectfloodlight.openflow.types.U32;
Jonathan Hart86e59352014-10-22 10:42:16 -070079import org.projectfloodlight.openflow.types.U64;
80import org.projectfloodlight.openflow.types.VlanPcp;
81import org.slf4j.Logger;
82import org.slf4j.LoggerFactory;
83
Jonathan Hart29afca32015-01-20 18:17:39 -080084import java.util.Collections;
85import java.util.LinkedList;
86import java.util.List;
87import java.util.Optional;
88
Jonathan Hart86e59352014-10-22 10:42:16 -070089/**
90 * Flow mod builder for OpenFlow 1.3+.
91 */
92public class FlowModBuilderVer13 extends FlowModBuilder {
93
alshabib10580802015-02-18 18:30:33 -080094 private final Logger log = LoggerFactory.getLogger(getClass());
Charles M.C. Chanfe421812015-01-12 18:20:51 +080095 private static final int OFPCML_NO_BUFFER = 0xffff;
Jonathan Hart86e59352014-10-22 10:42:16 -070096
97 private final TrafficTreatment treatment;
Jonathan Hart3c259162015-10-21 21:31:19 -070098 private final DeviceId deviceId;
Jonathan Hart86e59352014-10-22 10:42:16 -070099
100 /**
101 * Constructor for a flow mod builder for OpenFlow 1.3.
102 *
103 * @param flowRule the flow rule to transform into a flow mod
104 * @param factory the OpenFlow factory to use to build the flow mod
Pavlin Radoslavov119fd5c2014-11-25 19:08:19 -0800105 * @param xid the transaction ID
Jonathan Hart86e59352014-10-22 10:42:16 -0700106 */
Jonathan Hart3c259162015-10-21 21:31:19 -0700107 protected FlowModBuilderVer13(FlowRule flowRule, OFFactory factory, Optional<Long> xid,
108 Optional<DriverService> driverService) {
109 super(flowRule, factory, xid, driverService);
Jonathan Hart86e59352014-10-22 10:42:16 -0700110
111 this.treatment = flowRule.treatment();
Jonathan Hart3c259162015-10-21 21:31:19 -0700112 this.deviceId = flowRule.deviceId();
Jonathan Hart86e59352014-10-22 10:42:16 -0700113 }
114
115 @Override
116 public OFFlowAdd buildFlowAdd() {
117 Match match = buildMatch();
alshabib346b5b32015-03-06 00:42:16 -0800118 List<OFAction> deferredActions = buildActions(treatment.deferred());
119 List<OFAction> immediateActions = buildActions(treatment.immediate());
120 List<OFInstruction> instructions = Lists.newLinkedList();
Saurav Dascbe6de32015-03-01 18:30:46 -0800121
Jonathan Hartd4a8bba2014-10-28 12:44:20 -0700122
alshabib346b5b32015-03-06 00:42:16 -0800123 if (treatment.clearedDeferred()) {
124 instructions.add(factory().instructions().clearActions());
125 }
sangho1e575652015-05-14 00:39:53 -0700126 if (immediateActions.size() > 0) {
127 instructions.add(factory().instructions().applyActions(immediateActions));
128 }
alshabib346b5b32015-03-06 00:42:16 -0800129 if (deferredActions.size() > 0) {
130 instructions.add(factory().instructions().writeActions(deferredActions));
131 }
132 if (treatment.tableTransition() != null) {
133 instructions.add(buildTableGoto(treatment.tableTransition()));
Saurav Dascbe6de32015-03-01 18:30:46 -0800134 }
Saurav Das86af8f12015-05-25 23:55:33 -0700135 if (treatment.writeMetadata() != null) {
136 instructions.add(buildMetadata(treatment.writeMetadata()));
137 }
chengfane264bef2015-09-28 08:38:19 +0800138 if (treatment.metered() != null) {
139 instructions.add(buildMeter(treatment.metered()));
140 }
Jonathan Hart86e59352014-10-22 10:42:16 -0700141
142 long cookie = flowRule().id().value();
143
Jonathan Hart86e59352014-10-22 10:42:16 -0700144 OFFlowAdd fm = factory().buildFlowAdd()
Brian O'Connor427a1762014-11-19 18:40:32 -0800145 .setXid(xid)
Jonathan Hart86e59352014-10-22 10:42:16 -0700146 .setCookie(U64.of(cookie))
147 .setBufferId(OFBufferId.NO_BUFFER)
alshabib9af70072015-02-09 14:34:16 -0800148 .setInstructions(instructions)
Jonathan Hart86e59352014-10-22 10:42:16 -0700149 .setMatch(match)
150 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
151 .setPriority(flowRule().priority())
alshabib08d98982015-04-21 16:25:50 -0700152 .setTableId(TableId.of(flowRule().tableId()))
Jonathan Hart86e59352014-10-22 10:42:16 -0700153 .build();
154
155 return fm;
156 }
157
158 @Override
159 public OFFlowMod buildFlowMod() {
160 Match match = buildMatch();
alshabib346b5b32015-03-06 00:42:16 -0800161 List<OFAction> deferredActions = buildActions(treatment.deferred());
162 List<OFAction> immediateActions = buildActions(treatment.immediate());
163 List<OFInstruction> instructions = Lists.newLinkedList();
Jonathan Harteda33872015-02-18 10:22:32 -0800164
alshabib346b5b32015-03-06 00:42:16 -0800165
166 if (immediateActions.size() > 0) {
167 instructions.add(factory().instructions().applyActions(immediateActions));
168 }
169 if (treatment.clearedDeferred()) {
170 instructions.add(factory().instructions().clearActions());
171 }
172 if (deferredActions.size() > 0) {
173 instructions.add(factory().instructions().writeActions(deferredActions));
174 }
175 if (treatment.tableTransition() != null) {
176 instructions.add(buildTableGoto(treatment.tableTransition()));
Saurav Dascbe6de32015-03-01 18:30:46 -0800177 }
Saurav Das86af8f12015-05-25 23:55:33 -0700178 if (treatment.writeMetadata() != null) {
179 instructions.add(buildMetadata(treatment.writeMetadata()));
180 }
alshabib10c810b2015-08-18 16:59:04 -0700181 if (treatment.metered() != null) {
182 instructions.add(buildMeter(treatment.metered()));
183 }
Jonathan Hart86e59352014-10-22 10:42:16 -0700184
185 long cookie = flowRule().id().value();
186
Jonathan Hart86e59352014-10-22 10:42:16 -0700187 OFFlowMod fm = factory().buildFlowModify()
Brian O'Connor427a1762014-11-19 18:40:32 -0800188 .setXid(xid)
Jonathan Hart86e59352014-10-22 10:42:16 -0700189 .setCookie(U64.of(cookie))
190 .setBufferId(OFBufferId.NO_BUFFER)
alshabib9af70072015-02-09 14:34:16 -0800191 .setInstructions(instructions)
Jonathan Hart86e59352014-10-22 10:42:16 -0700192 .setMatch(match)
193 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
194 .setPriority(flowRule().priority())
alshabib08d98982015-04-21 16:25:50 -0700195 .setTableId(TableId.of(flowRule().tableId()))
Jonathan Hart86e59352014-10-22 10:42:16 -0700196 .build();
197
198 return fm;
199 }
200
201 @Override
202 public OFFlowDelete buildFlowDel() {
203 Match match = buildMatch();
Jonathan Hart86e59352014-10-22 10:42:16 -0700204
205 long cookie = flowRule().id().value();
206
207 OFFlowDelete fm = factory().buildFlowDelete()
Brian O'Connor427a1762014-11-19 18:40:32 -0800208 .setXid(xid)
Jonathan Hart86e59352014-10-22 10:42:16 -0700209 .setCookie(U64.of(cookie))
210 .setBufferId(OFBufferId.NO_BUFFER)
Jonathan Hart86e59352014-10-22 10:42:16 -0700211 .setMatch(match)
212 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
213 .setPriority(flowRule().priority())
alshabib08d98982015-04-21 16:25:50 -0700214 .setTableId(TableId.of(flowRule().tableId()))
Jonathan Hart86e59352014-10-22 10:42:16 -0700215 .build();
216
217 return fm;
218 }
219
alshabib346b5b32015-03-06 00:42:16 -0800220 private List<OFAction> buildActions(List<Instruction> treatments) {
Jonathan Hart86e59352014-10-22 10:42:16 -0700221 if (treatment == null) {
Sho SHIMIZU6601dd72015-05-11 19:00:29 -0700222 return Collections.emptyList();
Jonathan Hart86e59352014-10-22 10:42:16 -0700223 }
Sho SHIMIZU6601dd72015-05-11 19:00:29 -0700224
225 boolean tableFound = false;
226 List<OFAction> actions = new LinkedList<>();
alshabib346b5b32015-03-06 00:42:16 -0800227 for (Instruction i : treatments) {
Jonathan Hart86e59352014-10-22 10:42:16 -0700228 switch (i.type()) {
alshabib9af70072015-02-09 14:34:16 -0800229 case DROP:
Charles Chan7efabeb2015-09-28 15:12:19 -0700230 case NOACTION:
Sho SHIMIZUb35ed362015-04-28 11:05:19 -0700231 return Collections.emptyList();
alshabib9af70072015-02-09 14:34:16 -0800232 case L0MODIFICATION:
233 actions.add(buildL0Modification(i));
234 break;
235 case L2MODIFICATION:
236 actions.add(buildL2Modification(i));
237 break;
238 case L3MODIFICATION:
239 actions.add(buildL3Modification(i));
240 break;
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -0700241 case L4MODIFICATION:
242 actions.add(buildL4Modification(i));
243 break;
alshabib9af70072015-02-09 14:34:16 -0800244 case OUTPUT:
245 OutputInstruction out = (OutputInstruction) i;
246 OFActionOutput.Builder action = factory().actions().buildOutput()
247 .setPort(OFPort.of((int) out.port().toLong()));
248 if (out.port().equals(PortNumber.CONTROLLER)) {
249 action.setMaxLen(OFPCML_NO_BUFFER);
250 }
251 actions.add(action.build());
252 break;
253 case GROUP:
254 GroupInstruction group = (GroupInstruction) i;
255 OFActionGroup.Builder groupBuilder = factory().actions().buildGroup()
256 .setGroup(OFGroup.of(group.groupId().id()));
257 actions.add(groupBuilder.build());
258 break;
Steffen Gebertbbfdaaa2015-09-29 11:01:46 +0200259 case QUEUE:
260 SetQueueInstruction queue = (SetQueueInstruction) i;
261 OFActionSetQueue.Builder queueBuilder = factory().actions().buildSetQueue()
262 .setQueueId(queue.queueId());
263 actions.add(queueBuilder.build());
264 break;
alshabib10580802015-02-18 18:30:33 -0800265 case TABLE:
266 //FIXME: should not occur here.
Saurav Dascbe6de32015-03-01 18:30:46 -0800267 tableFound = true;
alshabib10580802015-02-18 18:30:33 -0800268 break;
Jonathan Hart3c259162015-10-21 21:31:19 -0700269 case EXTENSION:
270 actions.add(buildExtensionAction(((Instructions.ExtensionInstructionWrapper) i)
271 .extensionInstruction()));
272 break;
alshabib9af70072015-02-09 14:34:16 -0800273 default:
274 log.warn("Instruction type {} not yet implemented.", i.type());
Jonathan Hart86e59352014-10-22 10:42:16 -0700275 }
276 }
Saurav Dascbe6de32015-03-01 18:30:46 -0800277 if (tableFound && actions.isEmpty()) {
278 // handles the case where there are no actions, but there is
279 // a goto instruction for the next table
Sho SHIMIZU6601dd72015-05-11 19:00:29 -0700280 return Collections.emptyList();
Saurav Dascbe6de32015-03-01 18:30:46 -0800281 }
Jonathan Hart86e59352014-10-22 10:42:16 -0700282 return actions;
283 }
284
alshabib9af70072015-02-09 14:34:16 -0800285 private OFInstruction buildTableGoto(Instructions.TableTypeTransition i) {
286 OFInstruction instruction = factory().instructions().gotoTable(
alshabibd17abc22015-04-21 18:26:35 -0700287 TableId.of(i.tableId()));
alshabib9af70072015-02-09 14:34:16 -0800288 return instruction;
289 }
290
Saurav Das86af8f12015-05-25 23:55:33 -0700291 private OFInstruction buildMetadata(Instructions.MetadataInstruction m) {
292 OFInstruction instruction = factory().instructions().writeMetadata(
293 U64.of(m.metadata()), U64.of(m.metadataMask()));
294 return instruction;
295 }
296
alshabib10c810b2015-08-18 16:59:04 -0700297 private OFInstruction buildMeter(Instructions.MeterInstruction metered) {
298 return factory().instructions().meter(metered.meterId().id());
299 }
300
301
Jonathan Hart86e59352014-10-22 10:42:16 -0700302 private OFAction buildL0Modification(Instruction i) {
303 L0ModificationInstruction l0m = (L0ModificationInstruction) i;
304 switch (l0m.subtype()) {
Sho SHIMIZU5cd7ce92015-05-11 19:10:38 -0700305 case LAMBDA:
Sho SHIMIZUe397ffe2015-05-12 16:24:23 -0700306 return buildModLambdaInstruction((ModLambdaInstruction) i);
307 case OCH:
308 try {
309 return buildModOchSignalInstruction((ModOchSignalInstruction) i);
Sho SHIMIZUc17042d2015-05-28 12:07:23 -0700310 } catch (NoMappingFoundException e) {
Sho SHIMIZUe397ffe2015-05-12 16:24:23 -0700311 log.warn(e.getMessage());
312 break;
313 }
Sho SHIMIZU5cd7ce92015-05-11 19:10:38 -0700314 default:
315 log.warn("Unimplemented action type {}.", l0m.subtype());
316 break;
Jonathan Hart86e59352014-10-22 10:42:16 -0700317 }
318 return null;
319 }
320
Sho SHIMIZUe397ffe2015-05-12 16:24:23 -0700321 private OFAction buildModLambdaInstruction(ModLambdaInstruction instruction) {
322 return factory().actions().circuit(factory().oxms().ochSigidBasic(
323 new CircuitSignalID((byte) 1, (byte) 2, instruction.lambda(), (short) 1)));
324 }
325
326 private OFAction buildModOchSignalInstruction(ModOchSignalInstruction instruction) {
327 OchSignal signal = instruction.lambda();
Sho SHIMIZUc17042d2015-05-28 12:07:23 -0700328 byte gridType = OpenFlowValueMapper.lookupGridType(signal.gridType());
329 byte channelSpacing = OpenFlowValueMapper.lookupChannelSpacing(signal.channelSpacing());
Sho SHIMIZUe397ffe2015-05-12 16:24:23 -0700330
331 return factory().actions().circuit(factory().oxms().ochSigidBasic(
332 new CircuitSignalID(gridType, channelSpacing,
333 (short) signal.spacingMultiplier(), (short) signal.slotGranularity())
334 ));
335 }
336
Jonathan Hart86e59352014-10-22 10:42:16 -0700337 private OFAction buildL2Modification(Instruction i) {
338 L2ModificationInstruction l2m = (L2ModificationInstruction) i;
339 ModEtherInstruction eth;
340 OFOxm<?> oxm = null;
341 switch (l2m.subtype()) {
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800342 case ETH_DST:
343 eth = (ModEtherInstruction) l2m;
344 oxm = factory().oxms().ethDst(MacAddress.of(eth.mac().toLong()));
345 break;
346 case ETH_SRC:
347 eth = (ModEtherInstruction) l2m;
348 oxm = factory().oxms().ethSrc(MacAddress.of(eth.mac().toLong()));
349 break;
350 case VLAN_ID:
351 ModVlanIdInstruction vlanId = (ModVlanIdInstruction) l2m;
352 oxm = factory().oxms().vlanVid(OFVlanVidMatch.ofVlan(vlanId.vlanId().toShort()));
353 break;
354 case VLAN_PCP:
355 ModVlanPcpInstruction vlanPcp = (ModVlanPcpInstruction) l2m;
356 oxm = factory().oxms().vlanPcp(VlanPcp.of(vlanPcp.vlanPcp()));
357 break;
358 case MPLS_PUSH:
359 PushHeaderInstructions pushHeaderInstructions =
360 (PushHeaderInstructions) l2m;
361 return factory().actions().pushMpls(EthType.of(pushHeaderInstructions
alshabib7b808c52015-06-26 14:22:24 -0700362 .ethernetType().toShort()));
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800363 case MPLS_POP:
Jonathan Hart67fc0972015-03-19 15:21:20 -0700364 PushHeaderInstructions popHeaderInstructions =
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800365 (PushHeaderInstructions) l2m;
366 return factory().actions().popMpls(EthType.of(popHeaderInstructions
alshabib7b808c52015-06-26 14:22:24 -0700367 .ethernetType().toShort()));
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800368 case MPLS_LABEL:
369 ModMplsLabelInstruction mplsLabel =
370 (ModMplsLabelInstruction) l2m;
HIGUCHI Yuta04b49fc2015-08-28 09:58:58 -0700371 oxm = factory().oxms().mplsLabel(U32.of(mplsLabel.mplsLabel().toInt()));
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800372 break;
Saurav Das73a7dd42015-08-19 22:20:31 -0700373 case MPLS_BOS:
374 ModMplsBosInstruction mplsBos = (ModMplsBosInstruction) l2m;
375 oxm = factory().oxms()
376 .mplsBos(mplsBos.mplsBos() ? OFBooleanValue.TRUE
377 : OFBooleanValue.FALSE);
378 break;
sangho3f97a17d2015-01-29 22:56:29 -0800379 case DEC_MPLS_TTL:
380 return factory().actions().decMplsTtl();
Saurav Dasfbe25c52015-03-04 11:12:00 -0800381 case VLAN_POP:
382 return factory().actions().popVlan();
Jonathan Hart54b406b2015-03-06 16:24:14 -0800383 case VLAN_PUSH:
384 PushHeaderInstructions pushVlanInstruction = (PushHeaderInstructions) l2m;
385 return factory().actions().pushVlan(
alshabib7b808c52015-06-26 14:22:24 -0700386 EthType.of(pushVlanInstruction.ethernetType().toShort()));
Hyunsun Moona08c5d02015-07-14 17:53:00 -0700387 case TUNNEL_ID:
388 ModTunnelIdInstruction tunnelId = (ModTunnelIdInstruction) l2m;
389 oxm = factory().oxms().tunnelId(U64.of(tunnelId.tunnelId()));
390 break;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800391 default:
392 log.warn("Unimplemented action type {}.", l2m.subtype());
393 break;
Jonathan Hart86e59352014-10-22 10:42:16 -0700394 }
395
396 if (oxm != null) {
397 return factory().actions().buildSetField().setField(oxm).build();
398 }
399 return null;
400 }
401
402 private OFAction buildL3Modification(Instruction i) {
403 L3ModificationInstruction l3m = (L3ModificationInstruction) i;
404 ModIPInstruction ip;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800405 Ip4Address ip4;
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800406 Ip6Address ip6;
Jonathan Hart86e59352014-10-22 10:42:16 -0700407 OFOxm<?> oxm = null;
408 switch (l3m.subtype()) {
Sho SHIMIZU5cd7ce92015-05-11 19:10:38 -0700409 case IPV4_SRC:
410 ip = (ModIPInstruction) i;
411 ip4 = ip.ip().getIp4Address();
412 oxm = factory().oxms().ipv4Src(IPv4Address.of(ip4.toInt()));
413 break;
414 case IPV4_DST:
415 ip = (ModIPInstruction) i;
416 ip4 = ip.ip().getIp4Address();
417 oxm = factory().oxms().ipv4Dst(IPv4Address.of(ip4.toInt()));
418 break;
419 case IPV6_SRC:
420 ip = (ModIPInstruction) i;
421 ip6 = ip.ip().getIp6Address();
422 oxm = factory().oxms().ipv6Src(IPv6Address.of(ip6.toOctets()));
423 break;
424 case IPV6_DST:
425 ip = (ModIPInstruction) i;
426 ip6 = ip.ip().getIp6Address();
427 oxm = factory().oxms().ipv6Dst(IPv6Address.of(ip6.toOctets()));
428 break;
429 case IPV6_FLABEL:
430 ModIPv6FlowLabelInstruction flowLabelInstruction =
431 (ModIPv6FlowLabelInstruction) i;
432 int flowLabel = flowLabelInstruction.flowLabel();
433 oxm = factory().oxms().ipv6Flabel(IPv6FlowLabel.of(flowLabel));
434 break;
435 case DEC_TTL:
436 return factory().actions().decNwTtl();
437 case TTL_IN:
438 return factory().actions().copyTtlIn();
439 case TTL_OUT:
440 return factory().actions().copyTtlOut();
441 default:
442 log.warn("Unimplemented action type {}.", l3m.subtype());
443 break;
Jonathan Hart86e59352014-10-22 10:42:16 -0700444 }
445
446 if (oxm != null) {
447 return factory().actions().buildSetField().setField(oxm).build();
448 }
449 return null;
450 }
451
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -0700452 private OFAction buildL4Modification(Instruction i) {
453 L4ModificationInstruction l4m = (L4ModificationInstruction) i;
454 ModTransportPortInstruction tp;
455 OFOxm<?> oxm = null;
456 switch (l4m.subtype()) {
457 case TCP_SRC:
458 tp = (ModTransportPortInstruction) l4m;
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700459 oxm = factory().oxms().tcpSrc(TransportPort.of(tp.port().toInt()));
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -0700460 break;
461 case TCP_DST:
462 tp = (ModTransportPortInstruction) l4m;
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700463 oxm = factory().oxms().tcpDst(TransportPort.of(tp.port().toInt()));
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -0700464 break;
465 case UDP_SRC:
466 tp = (ModTransportPortInstruction) l4m;
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700467 oxm = factory().oxms().udpSrc(TransportPort.of(tp.port().toInt()));
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -0700468 break;
469 case UDP_DST:
470 tp = (ModTransportPortInstruction) l4m;
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700471 oxm = factory().oxms().udpDst(TransportPort.of(tp.port().toInt()));
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -0700472 break;
473 default:
474 log.warn("Unimplemented action type {}.", l4m.subtype());
475 break;
476 }
477
478 if (oxm != null) {
479 return factory().actions().buildSetField().setField(oxm).build();
480 }
481 return null;
482 }
483
Jonathan Hart3c259162015-10-21 21:31:19 -0700484 private OFAction buildExtensionAction(ExtensionInstruction i) {
485 if (!driverService.isPresent()) {
486 log.error("No driver service present");
487 return null;
488 }
489 Driver driver = driverService.get().getDriver(deviceId);
490 if (driver.hasBehaviour(ExtensionInterpreter.class)) {
491 DefaultDriverHandler handler =
492 new DefaultDriverHandler(new DefaultDriverData(driver, deviceId));
493 ExtensionInterpreter interpreter = handler.behaviour(ExtensionInterpreter.class);
494 return interpreter.mapInstruction(factory(), i);
495 }
496
497 return null;
498 }
499
Jonathan Hart86e59352014-10-22 10:42:16 -0700500}