blob: 3521ca4661e8737acc50b0ea89b0b9e29a9fbaa4 [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;
Jonathan Hart3c259162015-10-21 21:31:19 -070023import org.onosproject.net.driver.DefaultDriverData;
24import org.onosproject.net.driver.DefaultDriverHandler;
25import org.onosproject.net.driver.Driver;
26import org.onosproject.net.driver.DriverService;
Brian O'Connorabafb502014-12-02 22:26:20 -080027import org.onosproject.net.flow.FlowRule;
28import org.onosproject.net.flow.TrafficTreatment;
alshabib880b6442015-11-23 22:13:04 -080029import org.onosproject.net.flow.instructions.ExtensionTreatment;
Brian O'Connorabafb502014-12-02 22:26:20 -080030import org.onosproject.net.flow.instructions.Instruction;
alshabib9af70072015-02-09 14:34:16 -080031import org.onosproject.net.flow.instructions.Instructions;
sangho8995ac52015-02-04 11:29:03 -080032import org.onosproject.net.flow.instructions.Instructions.GroupInstruction;
alshabib9af70072015-02-09 14:34:16 -080033import org.onosproject.net.flow.instructions.Instructions.OutputInstruction;
Steffen Gebertbbfdaaa2015-09-29 11:01:46 +020034import org.onosproject.net.flow.instructions.Instructions.SetQueueInstruction;
Brian O'Connorabafb502014-12-02 22:26:20 -080035import org.onosproject.net.flow.instructions.L0ModificationInstruction;
36import org.onosproject.net.flow.instructions.L0ModificationInstruction.ModLambdaInstruction;
Sho SHIMIZUe397ffe2015-05-12 16:24:23 -070037import org.onosproject.net.flow.instructions.L0ModificationInstruction.ModOchSignalInstruction;
Brian O'Connorabafb502014-12-02 22:26:20 -080038import org.onosproject.net.flow.instructions.L2ModificationInstruction;
39import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
Saurav Das73a7dd42015-08-19 22:20:31 -070040import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsBosInstruction;
Jonathan Hart29afca32015-01-20 18:17:39 -080041import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsLabelInstruction;
Jonathan Hart3c259162015-10-21 21:31:19 -070042import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModTunnelIdInstruction;
Brian O'Connorabafb502014-12-02 22:26:20 -080043import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
44import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction;
Brian O'Connorabafb502014-12-02 22:26:20 -080045import org.onosproject.net.flow.instructions.L2ModificationInstruction.PushHeaderInstructions;
46import org.onosproject.net.flow.instructions.L3ModificationInstruction;
47import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
lishuai3cce60b2015-12-01 19:35:16 +080048import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModArpIPInstruction;
49import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModArpEthInstruction;
50import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModArpOpInstruction;
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -080051import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPv6FlowLabelInstruction;
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -070052import org.onosproject.net.flow.instructions.L4ModificationInstruction;
53import org.onosproject.net.flow.instructions.L4ModificationInstruction.ModTransportPortInstruction;
alshabib880b6442015-11-23 22:13:04 -080054import org.onosproject.openflow.controller.ExtensionTreatmentInterpreter;
Jonathan Hart86e59352014-10-22 10:42:16 -070055import org.projectfloodlight.openflow.protocol.OFFactory;
56import org.projectfloodlight.openflow.protocol.OFFlowAdd;
57import org.projectfloodlight.openflow.protocol.OFFlowDelete;
58import org.projectfloodlight.openflow.protocol.OFFlowMod;
59import org.projectfloodlight.openflow.protocol.OFFlowModFlags;
60import org.projectfloodlight.openflow.protocol.action.OFAction;
sangho8995ac52015-02-04 11:29:03 -080061import org.projectfloodlight.openflow.protocol.action.OFActionGroup;
Charles M.C. Chanfe421812015-01-12 18:20:51 +080062import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
Steffen Gebertbbfdaaa2015-09-29 11:01:46 +020063import org.projectfloodlight.openflow.protocol.action.OFActionSetQueue;
alshabib9af70072015-02-09 14:34:16 -080064import org.projectfloodlight.openflow.protocol.instruction.OFInstruction;
Jonathan Hart86e59352014-10-22 10:42:16 -070065import org.projectfloodlight.openflow.protocol.match.Match;
66import org.projectfloodlight.openflow.protocol.oxm.OFOxm;
lishuai3cce60b2015-12-01 19:35:16 +080067import org.projectfloodlight.openflow.types.ArpOpcode;
Jonathan Hart86e59352014-10-22 10:42:16 -070068import org.projectfloodlight.openflow.types.CircuitSignalID;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -080069import org.projectfloodlight.openflow.types.EthType;
Jonathan Hart86e59352014-10-22 10:42:16 -070070import org.projectfloodlight.openflow.types.IPv4Address;
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -080071import org.projectfloodlight.openflow.types.IPv6Address;
72import org.projectfloodlight.openflow.types.IPv6FlowLabel;
Jonathan Hart86e59352014-10-22 10:42:16 -070073import org.projectfloodlight.openflow.types.MacAddress;
Saurav Das73a7dd42015-08-19 22:20:31 -070074import org.projectfloodlight.openflow.types.OFBooleanValue;
Jonathan Hart86e59352014-10-22 10:42:16 -070075import org.projectfloodlight.openflow.types.OFBufferId;
sangho8995ac52015-02-04 11:29:03 -080076import org.projectfloodlight.openflow.types.OFGroup;
Jonathan Hart86e59352014-10-22 10:42:16 -070077import org.projectfloodlight.openflow.types.OFPort;
78import org.projectfloodlight.openflow.types.OFVlanVidMatch;
alshabib9af70072015-02-09 14:34:16 -080079import org.projectfloodlight.openflow.types.TableId;
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -070080import org.projectfloodlight.openflow.types.TransportPort;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -080081import org.projectfloodlight.openflow.types.U32;
Jonathan Hart86e59352014-10-22 10:42:16 -070082import org.projectfloodlight.openflow.types.U64;
83import org.projectfloodlight.openflow.types.VlanPcp;
84import org.slf4j.Logger;
85import org.slf4j.LoggerFactory;
86
Jonathan Hart29afca32015-01-20 18:17:39 -080087import java.util.Collections;
88import java.util.LinkedList;
89import java.util.List;
90import java.util.Optional;
91
Jonathan Hart86e59352014-10-22 10:42:16 -070092/**
93 * Flow mod builder for OpenFlow 1.3+.
94 */
95public class FlowModBuilderVer13 extends FlowModBuilder {
96
alshabib10580802015-02-18 18:30:33 -080097 private final Logger log = LoggerFactory.getLogger(getClass());
Charles M.C. Chanfe421812015-01-12 18:20:51 +080098 private static final int OFPCML_NO_BUFFER = 0xffff;
Jonathan Hart86e59352014-10-22 10:42:16 -070099
100 private final TrafficTreatment treatment;
101
102 /**
103 * Constructor for a flow mod builder for OpenFlow 1.3.
104 *
105 * @param flowRule the flow rule to transform into a flow mod
106 * @param factory the OpenFlow factory to use to build the flow mod
Pavlin Radoslavov119fd5c2014-11-25 19:08:19 -0800107 * @param xid the transaction ID
Charles Chan30ba4002015-11-05 14:45:16 -0800108 * @param driverService the device driver service
Jonathan Hart86e59352014-10-22 10:42:16 -0700109 */
Jonathan Hart3c259162015-10-21 21:31:19 -0700110 protected FlowModBuilderVer13(FlowRule flowRule, OFFactory factory, Optional<Long> xid,
111 Optional<DriverService> driverService) {
112 super(flowRule, factory, xid, driverService);
Jonathan Hart86e59352014-10-22 10:42:16 -0700113
114 this.treatment = flowRule.treatment();
115 }
116
117 @Override
118 public OFFlowAdd buildFlowAdd() {
119 Match match = buildMatch();
alshabib346b5b32015-03-06 00:42:16 -0800120 List<OFAction> deferredActions = buildActions(treatment.deferred());
121 List<OFAction> immediateActions = buildActions(treatment.immediate());
122 List<OFInstruction> instructions = Lists.newLinkedList();
Saurav Dascbe6de32015-03-01 18:30:46 -0800123
Jonathan Hartd4a8bba2014-10-28 12:44:20 -0700124
alshabib346b5b32015-03-06 00:42:16 -0800125 if (treatment.clearedDeferred()) {
126 instructions.add(factory().instructions().clearActions());
127 }
sangho1e575652015-05-14 00:39:53 -0700128 if (immediateActions.size() > 0) {
129 instructions.add(factory().instructions().applyActions(immediateActions));
130 }
alshabib346b5b32015-03-06 00:42:16 -0800131 if (deferredActions.size() > 0) {
132 instructions.add(factory().instructions().writeActions(deferredActions));
133 }
134 if (treatment.tableTransition() != null) {
135 instructions.add(buildTableGoto(treatment.tableTransition()));
Saurav Dascbe6de32015-03-01 18:30:46 -0800136 }
Saurav Das86af8f12015-05-25 23:55:33 -0700137 if (treatment.writeMetadata() != null) {
138 instructions.add(buildMetadata(treatment.writeMetadata()));
139 }
chengfane264bef2015-09-28 08:38:19 +0800140 if (treatment.metered() != null) {
141 instructions.add(buildMeter(treatment.metered()));
142 }
Jonathan Hart86e59352014-10-22 10:42:16 -0700143
144 long cookie = flowRule().id().value();
145
Jonathan Hart86e59352014-10-22 10:42:16 -0700146 OFFlowAdd fm = factory().buildFlowAdd()
Brian O'Connor427a1762014-11-19 18:40:32 -0800147 .setXid(xid)
Jonathan Hart86e59352014-10-22 10:42:16 -0700148 .setCookie(U64.of(cookie))
149 .setBufferId(OFBufferId.NO_BUFFER)
alshabib9af70072015-02-09 14:34:16 -0800150 .setInstructions(instructions)
Jonathan Hart86e59352014-10-22 10:42:16 -0700151 .setMatch(match)
152 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
153 .setPriority(flowRule().priority())
alshabib08d98982015-04-21 16:25:50 -0700154 .setTableId(TableId.of(flowRule().tableId()))
Jonathan Hart86e59352014-10-22 10:42:16 -0700155 .build();
156
157 return fm;
158 }
159
160 @Override
161 public OFFlowMod buildFlowMod() {
162 Match match = buildMatch();
alshabib346b5b32015-03-06 00:42:16 -0800163 List<OFAction> deferredActions = buildActions(treatment.deferred());
164 List<OFAction> immediateActions = buildActions(treatment.immediate());
165 List<OFInstruction> instructions = Lists.newLinkedList();
Jonathan Harteda33872015-02-18 10:22:32 -0800166
alshabib346b5b32015-03-06 00:42:16 -0800167
168 if (immediateActions.size() > 0) {
169 instructions.add(factory().instructions().applyActions(immediateActions));
170 }
171 if (treatment.clearedDeferred()) {
172 instructions.add(factory().instructions().clearActions());
173 }
174 if (deferredActions.size() > 0) {
175 instructions.add(factory().instructions().writeActions(deferredActions));
176 }
177 if (treatment.tableTransition() != null) {
178 instructions.add(buildTableGoto(treatment.tableTransition()));
Saurav Dascbe6de32015-03-01 18:30:46 -0800179 }
Saurav Das86af8f12015-05-25 23:55:33 -0700180 if (treatment.writeMetadata() != null) {
181 instructions.add(buildMetadata(treatment.writeMetadata()));
182 }
alshabib10c810b2015-08-18 16:59:04 -0700183 if (treatment.metered() != null) {
184 instructions.add(buildMeter(treatment.metered()));
185 }
Jonathan Hart86e59352014-10-22 10:42:16 -0700186
187 long cookie = flowRule().id().value();
188
Jonathan Hart86e59352014-10-22 10:42:16 -0700189 OFFlowMod fm = factory().buildFlowModify()
Brian O'Connor427a1762014-11-19 18:40:32 -0800190 .setXid(xid)
Jonathan Hart86e59352014-10-22 10:42:16 -0700191 .setCookie(U64.of(cookie))
192 .setBufferId(OFBufferId.NO_BUFFER)
alshabib9af70072015-02-09 14:34:16 -0800193 .setInstructions(instructions)
Jonathan Hart86e59352014-10-22 10:42:16 -0700194 .setMatch(match)
195 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
196 .setPriority(flowRule().priority())
alshabib08d98982015-04-21 16:25:50 -0700197 .setTableId(TableId.of(flowRule().tableId()))
Jonathan Hart86e59352014-10-22 10:42:16 -0700198 .build();
199
200 return fm;
201 }
202
203 @Override
204 public OFFlowDelete buildFlowDel() {
205 Match match = buildMatch();
Jonathan Hart86e59352014-10-22 10:42:16 -0700206
207 long cookie = flowRule().id().value();
208
209 OFFlowDelete fm = factory().buildFlowDelete()
Brian O'Connor427a1762014-11-19 18:40:32 -0800210 .setXid(xid)
Jonathan Hart86e59352014-10-22 10:42:16 -0700211 .setCookie(U64.of(cookie))
212 .setBufferId(OFBufferId.NO_BUFFER)
Jonathan Hart86e59352014-10-22 10:42:16 -0700213 .setMatch(match)
214 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
215 .setPriority(flowRule().priority())
alshabib08d98982015-04-21 16:25:50 -0700216 .setTableId(TableId.of(flowRule().tableId()))
Jonathan Hart86e59352014-10-22 10:42:16 -0700217 .build();
218
219 return fm;
220 }
221
alshabib346b5b32015-03-06 00:42:16 -0800222 private List<OFAction> buildActions(List<Instruction> treatments) {
Jonathan Hart86e59352014-10-22 10:42:16 -0700223 if (treatment == null) {
Sho SHIMIZU6601dd72015-05-11 19:00:29 -0700224 return Collections.emptyList();
Jonathan Hart86e59352014-10-22 10:42:16 -0700225 }
Sho SHIMIZU6601dd72015-05-11 19:00:29 -0700226
227 boolean tableFound = false;
228 List<OFAction> actions = new LinkedList<>();
alshabib346b5b32015-03-06 00:42:16 -0800229 for (Instruction i : treatments) {
Jonathan Hart86e59352014-10-22 10:42:16 -0700230 switch (i.type()) {
alshabib9af70072015-02-09 14:34:16 -0800231 case DROP:
Charles Chan7efabeb2015-09-28 15:12:19 -0700232 case NOACTION:
Sho SHIMIZUb35ed362015-04-28 11:05:19 -0700233 return Collections.emptyList();
alshabib9af70072015-02-09 14:34:16 -0800234 case L0MODIFICATION:
235 actions.add(buildL0Modification(i));
236 break;
237 case L2MODIFICATION:
238 actions.add(buildL2Modification(i));
239 break;
240 case L3MODIFICATION:
241 actions.add(buildL3Modification(i));
242 break;
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -0700243 case L4MODIFICATION:
244 actions.add(buildL4Modification(i));
245 break;
alshabib9af70072015-02-09 14:34:16 -0800246 case OUTPUT:
247 OutputInstruction out = (OutputInstruction) i;
248 OFActionOutput.Builder action = factory().actions().buildOutput()
249 .setPort(OFPort.of((int) out.port().toLong()));
250 if (out.port().equals(PortNumber.CONTROLLER)) {
251 action.setMaxLen(OFPCML_NO_BUFFER);
252 }
253 actions.add(action.build());
254 break;
255 case GROUP:
256 GroupInstruction group = (GroupInstruction) i;
257 OFActionGroup.Builder groupBuilder = factory().actions().buildGroup()
258 .setGroup(OFGroup.of(group.groupId().id()));
259 actions.add(groupBuilder.build());
260 break;
Steffen Gebertbbfdaaa2015-09-29 11:01:46 +0200261 case QUEUE:
262 SetQueueInstruction queue = (SetQueueInstruction) i;
263 OFActionSetQueue.Builder queueBuilder = factory().actions().buildSetQueue()
264 .setQueueId(queue.queueId());
265 actions.add(queueBuilder.build());
266 break;
alshabib10580802015-02-18 18:30:33 -0800267 case TABLE:
268 //FIXME: should not occur here.
Saurav Dascbe6de32015-03-01 18:30:46 -0800269 tableFound = true;
alshabib10580802015-02-18 18:30:33 -0800270 break;
Jonathan Hart3c259162015-10-21 21:31:19 -0700271 case EXTENSION:
272 actions.add(buildExtensionAction(((Instructions.ExtensionInstructionWrapper) i)
273 .extensionInstruction()));
274 break;
alshabib9af70072015-02-09 14:34:16 -0800275 default:
276 log.warn("Instruction type {} not yet implemented.", i.type());
Jonathan Hart86e59352014-10-22 10:42:16 -0700277 }
278 }
Saurav Dascbe6de32015-03-01 18:30:46 -0800279 if (tableFound && actions.isEmpty()) {
280 // handles the case where there are no actions, but there is
281 // a goto instruction for the next table
Sho SHIMIZU6601dd72015-05-11 19:00:29 -0700282 return Collections.emptyList();
Saurav Dascbe6de32015-03-01 18:30:46 -0800283 }
Jonathan Hart86e59352014-10-22 10:42:16 -0700284 return actions;
285 }
286
alshabib9af70072015-02-09 14:34:16 -0800287 private OFInstruction buildTableGoto(Instructions.TableTypeTransition i) {
288 OFInstruction instruction = factory().instructions().gotoTable(
alshabibd17abc22015-04-21 18:26:35 -0700289 TableId.of(i.tableId()));
alshabib9af70072015-02-09 14:34:16 -0800290 return instruction;
291 }
292
Saurav Das86af8f12015-05-25 23:55:33 -0700293 private OFInstruction buildMetadata(Instructions.MetadataInstruction m) {
294 OFInstruction instruction = factory().instructions().writeMetadata(
295 U64.of(m.metadata()), U64.of(m.metadataMask()));
296 return instruction;
297 }
298
alshabib10c810b2015-08-18 16:59:04 -0700299 private OFInstruction buildMeter(Instructions.MeterInstruction metered) {
300 return factory().instructions().meter(metered.meterId().id());
301 }
302
303
Jonathan Hart86e59352014-10-22 10:42:16 -0700304 private OFAction buildL0Modification(Instruction i) {
305 L0ModificationInstruction l0m = (L0ModificationInstruction) i;
306 switch (l0m.subtype()) {
Sho SHIMIZU5cd7ce92015-05-11 19:10:38 -0700307 case LAMBDA:
Sho SHIMIZUe397ffe2015-05-12 16:24:23 -0700308 return buildModLambdaInstruction((ModLambdaInstruction) i);
309 case OCH:
310 try {
311 return buildModOchSignalInstruction((ModOchSignalInstruction) i);
Sho SHIMIZUc17042d2015-05-28 12:07:23 -0700312 } catch (NoMappingFoundException e) {
Sho SHIMIZUe397ffe2015-05-12 16:24:23 -0700313 log.warn(e.getMessage());
314 break;
315 }
Sho SHIMIZU5cd7ce92015-05-11 19:10:38 -0700316 default:
317 log.warn("Unimplemented action type {}.", l0m.subtype());
318 break;
Jonathan Hart86e59352014-10-22 10:42:16 -0700319 }
320 return null;
321 }
322
Sho SHIMIZUe397ffe2015-05-12 16:24:23 -0700323 private OFAction buildModLambdaInstruction(ModLambdaInstruction instruction) {
Marc De Leenheerc2999f32015-11-20 15:52:16 -0800324 return factory().actions().circuit(factory().oxms().expOchSigId(
Sho SHIMIZUe397ffe2015-05-12 16:24:23 -0700325 new CircuitSignalID((byte) 1, (byte) 2, instruction.lambda(), (short) 1)));
326 }
327
328 private OFAction buildModOchSignalInstruction(ModOchSignalInstruction instruction) {
329 OchSignal signal = instruction.lambda();
Sho SHIMIZUc17042d2015-05-28 12:07:23 -0700330 byte gridType = OpenFlowValueMapper.lookupGridType(signal.gridType());
331 byte channelSpacing = OpenFlowValueMapper.lookupChannelSpacing(signal.channelSpacing());
Sho SHIMIZUe397ffe2015-05-12 16:24:23 -0700332
Marc De Leenheerc2999f32015-11-20 15:52:16 -0800333 return factory().actions().circuit(factory().oxms().expOchSigId(
Sho SHIMIZUe397ffe2015-05-12 16:24:23 -0700334 new CircuitSignalID(gridType, channelSpacing,
335 (short) signal.spacingMultiplier(), (short) signal.slotGranularity())
336 ));
337 }
338
Jonathan Hart86e59352014-10-22 10:42:16 -0700339 private OFAction buildL2Modification(Instruction i) {
340 L2ModificationInstruction l2m = (L2ModificationInstruction) i;
341 ModEtherInstruction eth;
342 OFOxm<?> oxm = null;
343 switch (l2m.subtype()) {
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800344 case ETH_DST:
345 eth = (ModEtherInstruction) l2m;
346 oxm = factory().oxms().ethDst(MacAddress.of(eth.mac().toLong()));
347 break;
348 case ETH_SRC:
349 eth = (ModEtherInstruction) l2m;
350 oxm = factory().oxms().ethSrc(MacAddress.of(eth.mac().toLong()));
351 break;
352 case VLAN_ID:
353 ModVlanIdInstruction vlanId = (ModVlanIdInstruction) l2m;
354 oxm = factory().oxms().vlanVid(OFVlanVidMatch.ofVlan(vlanId.vlanId().toShort()));
355 break;
356 case VLAN_PCP:
357 ModVlanPcpInstruction vlanPcp = (ModVlanPcpInstruction) l2m;
358 oxm = factory().oxms().vlanPcp(VlanPcp.of(vlanPcp.vlanPcp()));
359 break;
360 case MPLS_PUSH:
361 PushHeaderInstructions pushHeaderInstructions =
362 (PushHeaderInstructions) l2m;
363 return factory().actions().pushMpls(EthType.of(pushHeaderInstructions
alshabib7b808c52015-06-26 14:22:24 -0700364 .ethernetType().toShort()));
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800365 case MPLS_POP:
Jonathan Hart67fc0972015-03-19 15:21:20 -0700366 PushHeaderInstructions popHeaderInstructions =
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800367 (PushHeaderInstructions) l2m;
368 return factory().actions().popMpls(EthType.of(popHeaderInstructions
alshabib7b808c52015-06-26 14:22:24 -0700369 .ethernetType().toShort()));
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800370 case MPLS_LABEL:
371 ModMplsLabelInstruction mplsLabel =
372 (ModMplsLabelInstruction) l2m;
HIGUCHI Yuta04b49fc2015-08-28 09:58:58 -0700373 oxm = factory().oxms().mplsLabel(U32.of(mplsLabel.mplsLabel().toInt()));
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800374 break;
Saurav Das73a7dd42015-08-19 22:20:31 -0700375 case MPLS_BOS:
376 ModMplsBosInstruction mplsBos = (ModMplsBosInstruction) l2m;
377 oxm = factory().oxms()
378 .mplsBos(mplsBos.mplsBos() ? OFBooleanValue.TRUE
379 : OFBooleanValue.FALSE);
380 break;
sangho3f97a17d2015-01-29 22:56:29 -0800381 case DEC_MPLS_TTL:
382 return factory().actions().decMplsTtl();
Saurav Dasfbe25c52015-03-04 11:12:00 -0800383 case VLAN_POP:
384 return factory().actions().popVlan();
Jonathan Hart54b406b2015-03-06 16:24:14 -0800385 case VLAN_PUSH:
386 PushHeaderInstructions pushVlanInstruction = (PushHeaderInstructions) l2m;
387 return factory().actions().pushVlan(
alshabib7b808c52015-06-26 14:22:24 -0700388 EthType.of(pushVlanInstruction.ethernetType().toShort()));
Hyunsun Moona08c5d02015-07-14 17:53:00 -0700389 case TUNNEL_ID:
390 ModTunnelIdInstruction tunnelId = (ModTunnelIdInstruction) l2m;
391 oxm = factory().oxms().tunnelId(U64.of(tunnelId.tunnelId()));
392 break;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800393 default:
394 log.warn("Unimplemented action type {}.", l2m.subtype());
395 break;
Jonathan Hart86e59352014-10-22 10:42:16 -0700396 }
397
398 if (oxm != null) {
399 return factory().actions().buildSetField().setField(oxm).build();
400 }
401 return null;
402 }
403
404 private OFAction buildL3Modification(Instruction i) {
405 L3ModificationInstruction l3m = (L3ModificationInstruction) i;
406 ModIPInstruction ip;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800407 Ip4Address ip4;
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800408 Ip6Address ip6;
Jonathan Hart86e59352014-10-22 10:42:16 -0700409 OFOxm<?> oxm = null;
410 switch (l3m.subtype()) {
Sho SHIMIZU5cd7ce92015-05-11 19:10:38 -0700411 case IPV4_SRC:
412 ip = (ModIPInstruction) i;
413 ip4 = ip.ip().getIp4Address();
414 oxm = factory().oxms().ipv4Src(IPv4Address.of(ip4.toInt()));
415 break;
416 case IPV4_DST:
417 ip = (ModIPInstruction) i;
418 ip4 = ip.ip().getIp4Address();
419 oxm = factory().oxms().ipv4Dst(IPv4Address.of(ip4.toInt()));
420 break;
421 case IPV6_SRC:
422 ip = (ModIPInstruction) i;
423 ip6 = ip.ip().getIp6Address();
424 oxm = factory().oxms().ipv6Src(IPv6Address.of(ip6.toOctets()));
425 break;
426 case IPV6_DST:
427 ip = (ModIPInstruction) i;
428 ip6 = ip.ip().getIp6Address();
429 oxm = factory().oxms().ipv6Dst(IPv6Address.of(ip6.toOctets()));
430 break;
431 case IPV6_FLABEL:
432 ModIPv6FlowLabelInstruction flowLabelInstruction =
433 (ModIPv6FlowLabelInstruction) i;
434 int flowLabel = flowLabelInstruction.flowLabel();
435 oxm = factory().oxms().ipv6Flabel(IPv6FlowLabel.of(flowLabel));
436 break;
lishuai3cce60b2015-12-01 19:35:16 +0800437 case ARP_SPA:
438 ModArpIPInstruction aip = (ModArpIPInstruction) i;
439 ip4 = aip.ip().getIp4Address();
440 oxm = factory().oxms().arpSpa(IPv4Address.of(ip4.toInt()));
441 break;
442 case ARP_SHA:
443 ModArpEthInstruction ei = (ModArpEthInstruction) i;
444 oxm = factory().oxms().arpSha(MacAddress.of(ei.mac().toLong()));
445 break;
446 case ARP_OP:
447 ModArpOpInstruction oi = (ModArpOpInstruction) i;
448 oxm = factory().oxms().arpOp(ArpOpcode.of((int) oi.op()));
449 break;
Sho SHIMIZU5cd7ce92015-05-11 19:10:38 -0700450 case DEC_TTL:
451 return factory().actions().decNwTtl();
452 case TTL_IN:
453 return factory().actions().copyTtlIn();
454 case TTL_OUT:
455 return factory().actions().copyTtlOut();
456 default:
457 log.warn("Unimplemented action type {}.", l3m.subtype());
458 break;
Jonathan Hart86e59352014-10-22 10:42:16 -0700459 }
460
461 if (oxm != null) {
462 return factory().actions().buildSetField().setField(oxm).build();
463 }
464 return null;
465 }
466
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -0700467 private OFAction buildL4Modification(Instruction i) {
468 L4ModificationInstruction l4m = (L4ModificationInstruction) i;
469 ModTransportPortInstruction tp;
470 OFOxm<?> oxm = null;
471 switch (l4m.subtype()) {
472 case TCP_SRC:
473 tp = (ModTransportPortInstruction) l4m;
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700474 oxm = factory().oxms().tcpSrc(TransportPort.of(tp.port().toInt()));
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -0700475 break;
476 case TCP_DST:
477 tp = (ModTransportPortInstruction) l4m;
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700478 oxm = factory().oxms().tcpDst(TransportPort.of(tp.port().toInt()));
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -0700479 break;
480 case UDP_SRC:
481 tp = (ModTransportPortInstruction) l4m;
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700482 oxm = factory().oxms().udpSrc(TransportPort.of(tp.port().toInt()));
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -0700483 break;
484 case UDP_DST:
485 tp = (ModTransportPortInstruction) l4m;
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700486 oxm = factory().oxms().udpDst(TransportPort.of(tp.port().toInt()));
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -0700487 break;
488 default:
489 log.warn("Unimplemented action type {}.", l4m.subtype());
490 break;
491 }
492
493 if (oxm != null) {
494 return factory().actions().buildSetField().setField(oxm).build();
495 }
496 return null;
497 }
498
alshabib880b6442015-11-23 22:13:04 -0800499 private OFAction buildExtensionAction(ExtensionTreatment i) {
Jonathan Hart3c259162015-10-21 21:31:19 -0700500 if (!driverService.isPresent()) {
501 log.error("No driver service present");
502 return null;
503 }
504 Driver driver = driverService.get().getDriver(deviceId);
alshabib880b6442015-11-23 22:13:04 -0800505 if (driver.hasBehaviour(ExtensionTreatmentInterpreter.class)) {
Jonathan Hart3c259162015-10-21 21:31:19 -0700506 DefaultDriverHandler handler =
507 new DefaultDriverHandler(new DefaultDriverData(driver, deviceId));
alshabib880b6442015-11-23 22:13:04 -0800508 ExtensionTreatmentInterpreter interpreter = handler.behaviour(ExtensionTreatmentInterpreter.class);
Jonathan Hart3c259162015-10-21 21:31:19 -0700509 return interpreter.mapInstruction(factory(), i);
510 }
511
512 return null;
513 }
514
Jonathan Hart86e59352014-10-22 10:42:16 -0700515}