blob: 296f7e4b6a3ba1959a0bd385a84c570d519cf191 [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;
Yafit Hadar73514612015-11-04 10:14:21 +020022import org.onosproject.net.OduSignalId;
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;
alshabib880b6442015-11-23 22:13:04 -080030import org.onosproject.net.flow.instructions.ExtensionTreatment;
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;
Yafit Hadar73514612015-11-04 10:14:21 +020039import org.onosproject.net.flow.instructions.L1ModificationInstruction;
40import org.onosproject.net.flow.instructions.L1ModificationInstruction.ModOduSignalIdInstruction;
Brian O'Connorabafb502014-12-02 22:26:20 -080041import org.onosproject.net.flow.instructions.L2ModificationInstruction;
42import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
Saurav Das73a7dd42015-08-19 22:20:31 -070043import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsBosInstruction;
Jonathan Hart29afca32015-01-20 18:17:39 -080044import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsLabelInstruction;
Jonathan Hart3c259162015-10-21 21:31:19 -070045import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModTunnelIdInstruction;
Brian O'Connorabafb502014-12-02 22:26:20 -080046import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
47import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction;
Brian O'Connorabafb502014-12-02 22:26:20 -080048import org.onosproject.net.flow.instructions.L2ModificationInstruction.PushHeaderInstructions;
49import org.onosproject.net.flow.instructions.L3ModificationInstruction;
lishuai3cce60b2015-12-01 19:35:16 +080050import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModArpEthInstruction;
Jonathan Hart42feabd2016-02-03 17:56:21 -080051import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModArpIPInstruction;
lishuai3cce60b2015-12-01 19:35:16 +080052import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModArpOpInstruction;
Jonathan Hart42feabd2016-02-03 17:56:21 -080053import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -080054import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPv6FlowLabelInstruction;
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -070055import org.onosproject.net.flow.instructions.L4ModificationInstruction;
56import org.onosproject.net.flow.instructions.L4ModificationInstruction.ModTransportPortInstruction;
alshabib880b6442015-11-23 22:13:04 -080057import org.onosproject.openflow.controller.ExtensionTreatmentInterpreter;
Jonathan Hart86e59352014-10-22 10:42:16 -070058import org.projectfloodlight.openflow.protocol.OFFactory;
59import org.projectfloodlight.openflow.protocol.OFFlowAdd;
Jonathan Hart42feabd2016-02-03 17:56:21 -080060import org.projectfloodlight.openflow.protocol.OFFlowDeleteStrict;
Jonathan Hart86e59352014-10-22 10:42:16 -070061import org.projectfloodlight.openflow.protocol.OFFlowMod;
62import org.projectfloodlight.openflow.protocol.OFFlowModFlags;
63import org.projectfloodlight.openflow.protocol.action.OFAction;
sangho8995ac52015-02-04 11:29:03 -080064import org.projectfloodlight.openflow.protocol.action.OFActionGroup;
Charles M.C. Chanfe421812015-01-12 18:20:51 +080065import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
Steffen Gebertbbfdaaa2015-09-29 11:01:46 +020066import org.projectfloodlight.openflow.protocol.action.OFActionSetQueue;
alshabib9af70072015-02-09 14:34:16 -080067import org.projectfloodlight.openflow.protocol.instruction.OFInstruction;
Jonathan Hart86e59352014-10-22 10:42:16 -070068import org.projectfloodlight.openflow.protocol.match.Match;
69import org.projectfloodlight.openflow.protocol.oxm.OFOxm;
lishuai3cce60b2015-12-01 19:35:16 +080070import org.projectfloodlight.openflow.types.ArpOpcode;
Jonathan Hart86e59352014-10-22 10:42:16 -070071import org.projectfloodlight.openflow.types.CircuitSignalID;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -080072import org.projectfloodlight.openflow.types.EthType;
Jonathan Hart86e59352014-10-22 10:42:16 -070073import org.projectfloodlight.openflow.types.IPv4Address;
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -080074import org.projectfloodlight.openflow.types.IPv6Address;
75import org.projectfloodlight.openflow.types.IPv6FlowLabel;
Jonathan Hart86e59352014-10-22 10:42:16 -070076import org.projectfloodlight.openflow.types.MacAddress;
Saurav Das73a7dd42015-08-19 22:20:31 -070077import org.projectfloodlight.openflow.types.OFBooleanValue;
Jonathan Hart86e59352014-10-22 10:42:16 -070078import org.projectfloodlight.openflow.types.OFBufferId;
sangho8995ac52015-02-04 11:29:03 -080079import org.projectfloodlight.openflow.types.OFGroup;
Jonathan Hart86e59352014-10-22 10:42:16 -070080import org.projectfloodlight.openflow.types.OFPort;
81import org.projectfloodlight.openflow.types.OFVlanVidMatch;
Yafit Hadar73514612015-11-04 10:14:21 +020082import org.projectfloodlight.openflow.types.OduSignalID;
alshabib9af70072015-02-09 14:34:16 -080083import org.projectfloodlight.openflow.types.TableId;
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -070084import org.projectfloodlight.openflow.types.TransportPort;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -080085import org.projectfloodlight.openflow.types.U32;
Jonathan Hart86e59352014-10-22 10:42:16 -070086import org.projectfloodlight.openflow.types.U64;
87import org.projectfloodlight.openflow.types.VlanPcp;
88import org.slf4j.Logger;
89import org.slf4j.LoggerFactory;
90
Jonathan Hart29afca32015-01-20 18:17:39 -080091import java.util.Collections;
92import java.util.LinkedList;
93import java.util.List;
94import java.util.Optional;
95
Jonathan Hart86e59352014-10-22 10:42:16 -070096/**
97 * Flow mod builder for OpenFlow 1.3+.
98 */
99public class FlowModBuilderVer13 extends FlowModBuilder {
100
alshabib10580802015-02-18 18:30:33 -0800101 private final Logger log = LoggerFactory.getLogger(getClass());
Charles M.C. Chanfe421812015-01-12 18:20:51 +0800102 private static final int OFPCML_NO_BUFFER = 0xffff;
Jonathan Hart86e59352014-10-22 10:42:16 -0700103
104 private final TrafficTreatment treatment;
105
106 /**
107 * Constructor for a flow mod builder for OpenFlow 1.3.
108 *
109 * @param flowRule the flow rule to transform into a flow mod
110 * @param factory the OpenFlow factory to use to build the flow mod
Pavlin Radoslavov119fd5c2014-11-25 19:08:19 -0800111 * @param xid the transaction ID
Charles Chan30ba4002015-11-05 14:45:16 -0800112 * @param driverService the device driver service
Jonathan Hart86e59352014-10-22 10:42:16 -0700113 */
Jonathan Hart3c259162015-10-21 21:31:19 -0700114 protected FlowModBuilderVer13(FlowRule flowRule, OFFactory factory, Optional<Long> xid,
115 Optional<DriverService> driverService) {
116 super(flowRule, factory, xid, driverService);
Jonathan Hart86e59352014-10-22 10:42:16 -0700117
118 this.treatment = flowRule.treatment();
119 }
120
121 @Override
Jonathan Hart42feabd2016-02-03 17:56:21 -0800122 public OFFlowMod buildFlowAdd() {
Jonathan Hart86e59352014-10-22 10:42:16 -0700123 Match match = buildMatch();
alshabib346b5b32015-03-06 00:42:16 -0800124 List<OFAction> deferredActions = buildActions(treatment.deferred());
125 List<OFAction> immediateActions = buildActions(treatment.immediate());
126 List<OFInstruction> instructions = Lists.newLinkedList();
Saurav Dascbe6de32015-03-01 18:30:46 -0800127
Jonathan Hartd4a8bba2014-10-28 12:44:20 -0700128
alshabib346b5b32015-03-06 00:42:16 -0800129 if (treatment.clearedDeferred()) {
130 instructions.add(factory().instructions().clearActions());
131 }
sangho1e575652015-05-14 00:39:53 -0700132 if (immediateActions.size() > 0) {
133 instructions.add(factory().instructions().applyActions(immediateActions));
134 }
alshabib346b5b32015-03-06 00:42:16 -0800135 if (deferredActions.size() > 0) {
136 instructions.add(factory().instructions().writeActions(deferredActions));
137 }
138 if (treatment.tableTransition() != null) {
139 instructions.add(buildTableGoto(treatment.tableTransition()));
Saurav Dascbe6de32015-03-01 18:30:46 -0800140 }
Saurav Das86af8f12015-05-25 23:55:33 -0700141 if (treatment.writeMetadata() != null) {
142 instructions.add(buildMetadata(treatment.writeMetadata()));
143 }
chengfane264bef2015-09-28 08:38:19 +0800144 if (treatment.metered() != null) {
145 instructions.add(buildMeter(treatment.metered()));
146 }
Jonathan Hart86e59352014-10-22 10:42:16 -0700147
148 long cookie = flowRule().id().value();
149
Jonathan Hart86e59352014-10-22 10:42:16 -0700150 OFFlowAdd fm = factory().buildFlowAdd()
Brian O'Connor427a1762014-11-19 18:40:32 -0800151 .setXid(xid)
Jonathan Hart86e59352014-10-22 10:42:16 -0700152 .setCookie(U64.of(cookie))
153 .setBufferId(OFBufferId.NO_BUFFER)
alshabib9af70072015-02-09 14:34:16 -0800154 .setInstructions(instructions)
Jonathan Hart86e59352014-10-22 10:42:16 -0700155 .setMatch(match)
156 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
157 .setPriority(flowRule().priority())
alshabib08d98982015-04-21 16:25:50 -0700158 .setTableId(TableId.of(flowRule().tableId()))
Jonathan Hart86e59352014-10-22 10:42:16 -0700159 .build();
160
161 return fm;
162 }
163
164 @Override
165 public OFFlowMod buildFlowMod() {
166 Match match = buildMatch();
alshabib346b5b32015-03-06 00:42:16 -0800167 List<OFAction> deferredActions = buildActions(treatment.deferred());
168 List<OFAction> immediateActions = buildActions(treatment.immediate());
169 List<OFInstruction> instructions = Lists.newLinkedList();
Jonathan Harteda33872015-02-18 10:22:32 -0800170
alshabib346b5b32015-03-06 00:42:16 -0800171
172 if (immediateActions.size() > 0) {
173 instructions.add(factory().instructions().applyActions(immediateActions));
174 }
175 if (treatment.clearedDeferred()) {
176 instructions.add(factory().instructions().clearActions());
177 }
178 if (deferredActions.size() > 0) {
179 instructions.add(factory().instructions().writeActions(deferredActions));
180 }
181 if (treatment.tableTransition() != null) {
182 instructions.add(buildTableGoto(treatment.tableTransition()));
Saurav Dascbe6de32015-03-01 18:30:46 -0800183 }
Saurav Das86af8f12015-05-25 23:55:33 -0700184 if (treatment.writeMetadata() != null) {
185 instructions.add(buildMetadata(treatment.writeMetadata()));
186 }
alshabib10c810b2015-08-18 16:59:04 -0700187 if (treatment.metered() != null) {
188 instructions.add(buildMeter(treatment.metered()));
189 }
Jonathan Hart86e59352014-10-22 10:42:16 -0700190
191 long cookie = flowRule().id().value();
192
Jonathan Hart86e59352014-10-22 10:42:16 -0700193 OFFlowMod fm = factory().buildFlowModify()
Brian O'Connor427a1762014-11-19 18:40:32 -0800194 .setXid(xid)
Jonathan Hart86e59352014-10-22 10:42:16 -0700195 .setCookie(U64.of(cookie))
196 .setBufferId(OFBufferId.NO_BUFFER)
alshabib9af70072015-02-09 14:34:16 -0800197 .setInstructions(instructions)
Jonathan Hart86e59352014-10-22 10:42:16 -0700198 .setMatch(match)
199 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
200 .setPriority(flowRule().priority())
alshabib08d98982015-04-21 16:25:50 -0700201 .setTableId(TableId.of(flowRule().tableId()))
Jonathan Hart86e59352014-10-22 10:42:16 -0700202 .build();
203
204 return fm;
205 }
206
207 @Override
Jonathan Hart42feabd2016-02-03 17:56:21 -0800208 public OFFlowMod buildFlowDel() {
Jonathan Hart86e59352014-10-22 10:42:16 -0700209 Match match = buildMatch();
Jonathan Hart86e59352014-10-22 10:42:16 -0700210
211 long cookie = flowRule().id().value();
212
Jonathan Hart42feabd2016-02-03 17:56:21 -0800213 OFFlowDeleteStrict fm = factory().buildFlowDeleteStrict()
Brian O'Connor427a1762014-11-19 18:40:32 -0800214 .setXid(xid)
Jonathan Hart86e59352014-10-22 10:42:16 -0700215 .setCookie(U64.of(cookie))
216 .setBufferId(OFBufferId.NO_BUFFER)
Jonathan Hart86e59352014-10-22 10:42:16 -0700217 .setMatch(match)
218 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
219 .setPriority(flowRule().priority())
alshabib08d98982015-04-21 16:25:50 -0700220 .setTableId(TableId.of(flowRule().tableId()))
Jonathan Hart86e59352014-10-22 10:42:16 -0700221 .build();
222
223 return fm;
224 }
225
alshabib346b5b32015-03-06 00:42:16 -0800226 private List<OFAction> buildActions(List<Instruction> treatments) {
Jonathan Hart86e59352014-10-22 10:42:16 -0700227 if (treatment == null) {
Sho SHIMIZU6601dd72015-05-11 19:00:29 -0700228 return Collections.emptyList();
Jonathan Hart86e59352014-10-22 10:42:16 -0700229 }
Sho SHIMIZU6601dd72015-05-11 19:00:29 -0700230
231 boolean tableFound = false;
232 List<OFAction> actions = new LinkedList<>();
alshabib346b5b32015-03-06 00:42:16 -0800233 for (Instruction i : treatments) {
Jonathan Hart86e59352014-10-22 10:42:16 -0700234 switch (i.type()) {
alshabib9af70072015-02-09 14:34:16 -0800235 case DROP:
Charles Chan7efabeb2015-09-28 15:12:19 -0700236 case NOACTION:
Sho SHIMIZUb35ed362015-04-28 11:05:19 -0700237 return Collections.emptyList();
alshabib9af70072015-02-09 14:34:16 -0800238 case L0MODIFICATION:
239 actions.add(buildL0Modification(i));
240 break;
Yafit Hadar73514612015-11-04 10:14:21 +0200241 case L1MODIFICATION:
242 actions.add(buildL1Modification(i));
243 break;
alshabib9af70072015-02-09 14:34:16 -0800244 case L2MODIFICATION:
245 actions.add(buildL2Modification(i));
246 break;
247 case L3MODIFICATION:
248 actions.add(buildL3Modification(i));
249 break;
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -0700250 case L4MODIFICATION:
251 actions.add(buildL4Modification(i));
252 break;
alshabib9af70072015-02-09 14:34:16 -0800253 case OUTPUT:
254 OutputInstruction out = (OutputInstruction) i;
255 OFActionOutput.Builder action = factory().actions().buildOutput()
256 .setPort(OFPort.of((int) out.port().toLong()));
257 if (out.port().equals(PortNumber.CONTROLLER)) {
258 action.setMaxLen(OFPCML_NO_BUFFER);
259 }
260 actions.add(action.build());
261 break;
262 case GROUP:
263 GroupInstruction group = (GroupInstruction) i;
264 OFActionGroup.Builder groupBuilder = factory().actions().buildGroup()
265 .setGroup(OFGroup.of(group.groupId().id()));
266 actions.add(groupBuilder.build());
267 break;
Steffen Gebertbbfdaaa2015-09-29 11:01:46 +0200268 case QUEUE:
269 SetQueueInstruction queue = (SetQueueInstruction) i;
270 OFActionSetQueue.Builder queueBuilder = factory().actions().buildSetQueue()
271 .setQueueId(queue.queueId());
272 actions.add(queueBuilder.build());
273 break;
alshabib10580802015-02-18 18:30:33 -0800274 case TABLE:
275 //FIXME: should not occur here.
Saurav Dascbe6de32015-03-01 18:30:46 -0800276 tableFound = true;
alshabib10580802015-02-18 18:30:33 -0800277 break;
Jonathan Hart3c259162015-10-21 21:31:19 -0700278 case EXTENSION:
279 actions.add(buildExtensionAction(((Instructions.ExtensionInstructionWrapper) i)
280 .extensionInstruction()));
281 break;
alshabib9af70072015-02-09 14:34:16 -0800282 default:
283 log.warn("Instruction type {} not yet implemented.", i.type());
Jonathan Hart86e59352014-10-22 10:42:16 -0700284 }
285 }
Saurav Dascbe6de32015-03-01 18:30:46 -0800286 if (tableFound && actions.isEmpty()) {
287 // handles the case where there are no actions, but there is
288 // a goto instruction for the next table
Sho SHIMIZU6601dd72015-05-11 19:00:29 -0700289 return Collections.emptyList();
Saurav Dascbe6de32015-03-01 18:30:46 -0800290 }
Jonathan Hart86e59352014-10-22 10:42:16 -0700291 return actions;
292 }
293
alshabib9af70072015-02-09 14:34:16 -0800294 private OFInstruction buildTableGoto(Instructions.TableTypeTransition i) {
295 OFInstruction instruction = factory().instructions().gotoTable(
alshabibd17abc22015-04-21 18:26:35 -0700296 TableId.of(i.tableId()));
alshabib9af70072015-02-09 14:34:16 -0800297 return instruction;
298 }
299
Saurav Das86af8f12015-05-25 23:55:33 -0700300 private OFInstruction buildMetadata(Instructions.MetadataInstruction m) {
301 OFInstruction instruction = factory().instructions().writeMetadata(
302 U64.of(m.metadata()), U64.of(m.metadataMask()));
303 return instruction;
304 }
305
alshabib10c810b2015-08-18 16:59:04 -0700306 private OFInstruction buildMeter(Instructions.MeterInstruction metered) {
307 return factory().instructions().meter(metered.meterId().id());
308 }
309
310
Jonathan Hart86e59352014-10-22 10:42:16 -0700311 private OFAction buildL0Modification(Instruction i) {
312 L0ModificationInstruction l0m = (L0ModificationInstruction) i;
Yafit Hadar73514612015-11-04 10:14:21 +0200313 OFOxm<?> oxm = null;
Jonathan Hart86e59352014-10-22 10:42:16 -0700314 switch (l0m.subtype()) {
Sho SHIMIZU5cd7ce92015-05-11 19:10:38 -0700315 case LAMBDA:
Sho SHIMIZUe397ffe2015-05-12 16:24:23 -0700316 return buildModLambdaInstruction((ModLambdaInstruction) i);
317 case OCH:
318 try {
Yafit Hadar73514612015-11-04 10:14:21 +0200319 ModOchSignalInstruction modOchSignalInstruction = (ModOchSignalInstruction) l0m;
320 OchSignal signal = modOchSignalInstruction.lambda();
321 byte gridType = OpenFlowValueMapper.lookupGridType(signal.gridType());
322 byte channelSpacing = OpenFlowValueMapper.lookupChannelSpacing(signal.channelSpacing());
323 oxm = factory().oxms().expOchSigId(
324 new CircuitSignalID(gridType, channelSpacing,
325 (short) signal.spacingMultiplier(), (short) signal.slotGranularity()));
Sho SHIMIZUc17042d2015-05-28 12:07:23 -0700326 } catch (NoMappingFoundException e) {
Sho SHIMIZUe397ffe2015-05-12 16:24:23 -0700327 log.warn(e.getMessage());
328 break;
329 }
Yafit Hadar73514612015-11-04 10:14:21 +0200330 break;
Sho SHIMIZU5cd7ce92015-05-11 19:10:38 -0700331 default:
332 log.warn("Unimplemented action type {}.", l0m.subtype());
333 break;
Jonathan Hart86e59352014-10-22 10:42:16 -0700334 }
Yafit Hadar73514612015-11-04 10:14:21 +0200335 if (oxm != null) {
336 return factory().actions().buildSetField().setField(oxm).build();
337 }
Jonathan Hart86e59352014-10-22 10:42:16 -0700338 return null;
339 }
340
Sho SHIMIZUe397ffe2015-05-12 16:24:23 -0700341 private OFAction buildModLambdaInstruction(ModLambdaInstruction instruction) {
Marc De Leenheerc2999f32015-11-20 15:52:16 -0800342 return factory().actions().circuit(factory().oxms().expOchSigId(
Sho SHIMIZUe397ffe2015-05-12 16:24:23 -0700343 new CircuitSignalID((byte) 1, (byte) 2, instruction.lambda(), (short) 1)));
344 }
345
346 private OFAction buildModOchSignalInstruction(ModOchSignalInstruction instruction) {
347 OchSignal signal = instruction.lambda();
Sho SHIMIZUc17042d2015-05-28 12:07:23 -0700348 byte gridType = OpenFlowValueMapper.lookupGridType(signal.gridType());
349 byte channelSpacing = OpenFlowValueMapper.lookupChannelSpacing(signal.channelSpacing());
Sho SHIMIZUe397ffe2015-05-12 16:24:23 -0700350
Marc De Leenheerc2999f32015-11-20 15:52:16 -0800351 return factory().actions().circuit(factory().oxms().expOchSigId(
Sho SHIMIZUe397ffe2015-05-12 16:24:23 -0700352 new CircuitSignalID(gridType, channelSpacing,
353 (short) signal.spacingMultiplier(), (short) signal.slotGranularity())
354 ));
355 }
356
Yafit Hadar73514612015-11-04 10:14:21 +0200357 private OFAction buildL1Modification(Instruction i) {
358 L1ModificationInstruction l1m = (L1ModificationInstruction) i;
359 OFOxm<?> oxm = null;
360 switch (l1m.subtype()) {
361 case ODU_SIGID:
362 ModOduSignalIdInstruction modOduSignalIdInstruction = (ModOduSignalIdInstruction) l1m;
363 OduSignalId oduSignalId = modOduSignalIdInstruction.oduSignalId();
364
365 OduSignalID oduSignalID = new OduSignalID((short) oduSignalId.tributaryPortNumber(),
366 (short) oduSignalId.tributarySlotLength(),
367 oduSignalId.tributarySlotBitmap());
368
369 oxm = factory().oxms().expOduSigId(oduSignalID);
370 break;
371 default:
372 log.warn("Unimplemented action type {}.", l1m.subtype());
373 break;
374 }
375
376 if (oxm != null) {
377 return factory().actions().buildSetField().setField(oxm).build();
378 }
379 return null;
380 }
381
Jonathan Hart86e59352014-10-22 10:42:16 -0700382 private OFAction buildL2Modification(Instruction i) {
383 L2ModificationInstruction l2m = (L2ModificationInstruction) i;
384 ModEtherInstruction eth;
385 OFOxm<?> oxm = null;
386 switch (l2m.subtype()) {
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800387 case ETH_DST:
388 eth = (ModEtherInstruction) l2m;
389 oxm = factory().oxms().ethDst(MacAddress.of(eth.mac().toLong()));
390 break;
391 case ETH_SRC:
392 eth = (ModEtherInstruction) l2m;
393 oxm = factory().oxms().ethSrc(MacAddress.of(eth.mac().toLong()));
394 break;
395 case VLAN_ID:
396 ModVlanIdInstruction vlanId = (ModVlanIdInstruction) l2m;
397 oxm = factory().oxms().vlanVid(OFVlanVidMatch.ofVlan(vlanId.vlanId().toShort()));
398 break;
399 case VLAN_PCP:
400 ModVlanPcpInstruction vlanPcp = (ModVlanPcpInstruction) l2m;
401 oxm = factory().oxms().vlanPcp(VlanPcp.of(vlanPcp.vlanPcp()));
402 break;
403 case MPLS_PUSH:
404 PushHeaderInstructions pushHeaderInstructions =
405 (PushHeaderInstructions) l2m;
406 return factory().actions().pushMpls(EthType.of(pushHeaderInstructions
alshabib7b808c52015-06-26 14:22:24 -0700407 .ethernetType().toShort()));
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800408 case MPLS_POP:
Jonathan Hart67fc0972015-03-19 15:21:20 -0700409 PushHeaderInstructions popHeaderInstructions =
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800410 (PushHeaderInstructions) l2m;
411 return factory().actions().popMpls(EthType.of(popHeaderInstructions
alshabib7b808c52015-06-26 14:22:24 -0700412 .ethernetType().toShort()));
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800413 case MPLS_LABEL:
414 ModMplsLabelInstruction mplsLabel =
415 (ModMplsLabelInstruction) l2m;
Ray Milkey125572b2016-02-22 16:48:17 -0800416 oxm = factory().oxms().mplsLabel(U32.of(mplsLabel.label().toInt()));
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800417 break;
Saurav Das73a7dd42015-08-19 22:20:31 -0700418 case MPLS_BOS:
419 ModMplsBosInstruction mplsBos = (ModMplsBosInstruction) l2m;
420 oxm = factory().oxms()
421 .mplsBos(mplsBos.mplsBos() ? OFBooleanValue.TRUE
422 : OFBooleanValue.FALSE);
423 break;
sangho3f97a17d2015-01-29 22:56:29 -0800424 case DEC_MPLS_TTL:
425 return factory().actions().decMplsTtl();
Saurav Dasfbe25c52015-03-04 11:12:00 -0800426 case VLAN_POP:
427 return factory().actions().popVlan();
Jonathan Hart54b406b2015-03-06 16:24:14 -0800428 case VLAN_PUSH:
429 PushHeaderInstructions pushVlanInstruction = (PushHeaderInstructions) l2m;
430 return factory().actions().pushVlan(
alshabib7b808c52015-06-26 14:22:24 -0700431 EthType.of(pushVlanInstruction.ethernetType().toShort()));
Hyunsun Moona08c5d02015-07-14 17:53:00 -0700432 case TUNNEL_ID:
433 ModTunnelIdInstruction tunnelId = (ModTunnelIdInstruction) l2m;
434 oxm = factory().oxms().tunnelId(U64.of(tunnelId.tunnelId()));
435 break;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800436 default:
437 log.warn("Unimplemented action type {}.", l2m.subtype());
438 break;
Jonathan Hart86e59352014-10-22 10:42:16 -0700439 }
440
441 if (oxm != null) {
442 return factory().actions().buildSetField().setField(oxm).build();
443 }
444 return null;
445 }
446
447 private OFAction buildL3Modification(Instruction i) {
448 L3ModificationInstruction l3m = (L3ModificationInstruction) i;
449 ModIPInstruction ip;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800450 Ip4Address ip4;
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800451 Ip6Address ip6;
Jonathan Hart86e59352014-10-22 10:42:16 -0700452 OFOxm<?> oxm = null;
453 switch (l3m.subtype()) {
Sho SHIMIZU5cd7ce92015-05-11 19:10:38 -0700454 case IPV4_SRC:
455 ip = (ModIPInstruction) i;
456 ip4 = ip.ip().getIp4Address();
457 oxm = factory().oxms().ipv4Src(IPv4Address.of(ip4.toInt()));
458 break;
459 case IPV4_DST:
460 ip = (ModIPInstruction) i;
461 ip4 = ip.ip().getIp4Address();
462 oxm = factory().oxms().ipv4Dst(IPv4Address.of(ip4.toInt()));
463 break;
464 case IPV6_SRC:
465 ip = (ModIPInstruction) i;
466 ip6 = ip.ip().getIp6Address();
467 oxm = factory().oxms().ipv6Src(IPv6Address.of(ip6.toOctets()));
468 break;
469 case IPV6_DST:
470 ip = (ModIPInstruction) i;
471 ip6 = ip.ip().getIp6Address();
472 oxm = factory().oxms().ipv6Dst(IPv6Address.of(ip6.toOctets()));
473 break;
474 case IPV6_FLABEL:
475 ModIPv6FlowLabelInstruction flowLabelInstruction =
476 (ModIPv6FlowLabelInstruction) i;
477 int flowLabel = flowLabelInstruction.flowLabel();
478 oxm = factory().oxms().ipv6Flabel(IPv6FlowLabel.of(flowLabel));
479 break;
lishuai3cce60b2015-12-01 19:35:16 +0800480 case ARP_SPA:
481 ModArpIPInstruction aip = (ModArpIPInstruction) i;
482 ip4 = aip.ip().getIp4Address();
483 oxm = factory().oxms().arpSpa(IPv4Address.of(ip4.toInt()));
484 break;
485 case ARP_SHA:
486 ModArpEthInstruction ei = (ModArpEthInstruction) i;
487 oxm = factory().oxms().arpSha(MacAddress.of(ei.mac().toLong()));
488 break;
489 case ARP_OP:
490 ModArpOpInstruction oi = (ModArpOpInstruction) i;
491 oxm = factory().oxms().arpOp(ArpOpcode.of((int) oi.op()));
492 break;
Sho SHIMIZU5cd7ce92015-05-11 19:10:38 -0700493 case DEC_TTL:
494 return factory().actions().decNwTtl();
495 case TTL_IN:
496 return factory().actions().copyTtlIn();
497 case TTL_OUT:
498 return factory().actions().copyTtlOut();
499 default:
500 log.warn("Unimplemented action type {}.", l3m.subtype());
501 break;
Jonathan Hart86e59352014-10-22 10:42:16 -0700502 }
503
504 if (oxm != null) {
505 return factory().actions().buildSetField().setField(oxm).build();
506 }
507 return null;
508 }
509
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -0700510 private OFAction buildL4Modification(Instruction i) {
511 L4ModificationInstruction l4m = (L4ModificationInstruction) i;
512 ModTransportPortInstruction tp;
513 OFOxm<?> oxm = null;
514 switch (l4m.subtype()) {
515 case TCP_SRC:
516 tp = (ModTransportPortInstruction) l4m;
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700517 oxm = factory().oxms().tcpSrc(TransportPort.of(tp.port().toInt()));
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -0700518 break;
519 case TCP_DST:
520 tp = (ModTransportPortInstruction) l4m;
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700521 oxm = factory().oxms().tcpDst(TransportPort.of(tp.port().toInt()));
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -0700522 break;
523 case UDP_SRC:
524 tp = (ModTransportPortInstruction) l4m;
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700525 oxm = factory().oxms().udpSrc(TransportPort.of(tp.port().toInt()));
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -0700526 break;
527 case UDP_DST:
528 tp = (ModTransportPortInstruction) l4m;
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700529 oxm = factory().oxms().udpDst(TransportPort.of(tp.port().toInt()));
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -0700530 break;
531 default:
532 log.warn("Unimplemented action type {}.", l4m.subtype());
533 break;
534 }
535
536 if (oxm != null) {
537 return factory().actions().buildSetField().setField(oxm).build();
538 }
539 return null;
540 }
541
alshabib880b6442015-11-23 22:13:04 -0800542 private OFAction buildExtensionAction(ExtensionTreatment i) {
Jonathan Hart3c259162015-10-21 21:31:19 -0700543 if (!driverService.isPresent()) {
544 log.error("No driver service present");
545 return null;
546 }
547 Driver driver = driverService.get().getDriver(deviceId);
alshabib880b6442015-11-23 22:13:04 -0800548 if (driver.hasBehaviour(ExtensionTreatmentInterpreter.class)) {
Jonathan Hart3c259162015-10-21 21:31:19 -0700549 DefaultDriverHandler handler =
550 new DefaultDriverHandler(new DefaultDriverData(driver, deviceId));
alshabib880b6442015-11-23 22:13:04 -0800551 ExtensionTreatmentInterpreter interpreter = handler.behaviour(ExtensionTreatmentInterpreter.class);
Jonathan Hart3c259162015-10-21 21:31:19 -0700552 return interpreter.mapInstruction(factory(), i);
553 }
554
555 return null;
556 }
557
Jonathan Hart86e59352014-10-22 10:42:16 -0700558}