2 * Copyright (c) 2013 Ericsson. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.openflowplugin.openflow.md.core.sal.convertor;
11 import java.math.BigInteger;
12 import java.util.ArrayList;
13 import java.util.List;
15 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.flowflag.FlowFlagReactor;
16 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.match.MatchReactor;
17 import org.opendaylight.openflowplugin.openflow.md.util.ByteUtil;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.UpdatedFlow;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ClearActionsCase;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.GoToTableCase;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.MeterCase;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteActionsCase;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteMetadataCase;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActions;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.clear.actions._case.ClearActions;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.go.to.table._case.GoToTable;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.meter._case.Meter;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.write.actions._case.WriteActions;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.write.metadata._case.WriteMetadata;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ActionsInstruction;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ActionsInstructionBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MetadataInstruction;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MetadataInstructionBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MeterIdInstruction;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MeterIdInstructionBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.TableIdInstruction;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.TableIdInstructionBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.Instructions;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.InstructionsBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowModCommand;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MatchTypeBase;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableId;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.OxmMatchType;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.MatchEntries;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInput;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInputBuilder;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
56 * Utility class for converting a MD-SAL Flow into the OF flow mod
58 public class FlowConvertor {
59 private static final Logger logger = LoggerFactory.getLogger(FlowConvertor.class);
61 // Default values for when things are null
62 private static final BigInteger DEFAULT_COOKIE = BigInteger.ZERO;
63 private static final BigInteger DEFAULT_COOKIE_MASK = BigInteger.ZERO;
64 private static final TableId DEFAULT_TABLE_ID = new TableId(new Long(0));
65 private static final Integer DEFAULT_IDLE_TIMEOUT = new Integer(5 * 60);
66 private static final Integer DEFAULT_HARD_TIMEOUT = new Integer(10 * 60);
67 private static final Integer DEFAULT_PRIORITY = Integer.parseInt("8000", 16);
68 private static final Long DEFAULT_BUFFER_ID = Long.parseLong("ffffffff", 16);
69 private static final Long OFPP_ANY = Long.parseLong("ffffffff", 16);
70 private static final Long DEFAULT_OUT_PORT = OFPP_ANY;
71 private static final Long OFPG_ANY = Long.parseLong("ffffffff", 16);
72 private static final Long DEFAULT_OUT_GROUP = OFPG_ANY;
73 /** flow flag: remove */
74 public static final boolean DEFAULT_OFPFF_FLOW_REM = true;
75 /** flow flag: check overlap */
76 public static final boolean DEFAULT_OFPFF_CHECK_OVERLAP = false;
77 /** flow flag: reset counts */
78 public static final boolean DEFAULT_OFPFF_RESET_COUNTS = false;
79 /** flow flag: don't keep track of packet counts */
80 public static final boolean DEFAULT_OFPFF_NO_PKT_COUNTS = false;
81 /** flow flag: don't keep track of byte counts */
82 public static final boolean DEFAULT_OFPFF_NO_BYT_COUNTS = false;
83 /** flow flag: emergency [OFP-1.0] */
84 public static final boolean DEFAULT_OFPFF_EMERGENCY = false;
86 public static final Class<? extends MatchTypeBase> DEFAULT_MATCH_TYPE = OxmMatchType.class;
87 /** default match entries - empty */
88 public static final List<MatchEntries> DEFAULT_MATCH_ENTRIES = new ArrayList<MatchEntries>();
90 public static FlowModInput toFlowModInput(Flow flow, short version) {
91 FlowModInputBuilder flowMod = new FlowModInputBuilder();
92 if (flow.getCookie() != null) {
93 flowMod.setCookie(flow.getCookie());
95 flowMod.setCookie(DEFAULT_COOKIE);
98 if (flow.getCookieMask() != null) {
99 flowMod.setCookieMask(new BigInteger(flow.getCookieMask().toString()));
101 flowMod.setCookieMask(DEFAULT_COOKIE_MASK);
104 if (flow.getTableId() != null) {
105 flowMod.setTableId(new TableId(flow.getTableId().longValue()));
107 flowMod.setTableId(DEFAULT_TABLE_ID);
110 if (flow instanceof AddFlowInput) {
111 flowMod.setCommand(FlowModCommand.OFPFCADD);
112 } else if (flow instanceof RemoveFlowInput) {
113 if (flow.isStrict() != null && flow.isStrict()) {
114 flowMod.setCommand(FlowModCommand.OFPFCDELETESTRICT);
116 flowMod.setCommand(FlowModCommand.OFPFCDELETE);
118 } else if (flow instanceof UpdatedFlow) {
119 if (flow.isStrict() != null && flow.isStrict()) {
120 flowMod.setCommand(FlowModCommand.OFPFCMODIFYSTRICT);
122 flowMod.setCommand(FlowModCommand.OFPFCMODIFY);
125 if (flow.getIdleTimeout() != null) {
126 flowMod.setIdleTimeout(flow.getIdleTimeout());
128 flowMod.setIdleTimeout(DEFAULT_IDLE_TIMEOUT);
130 if (flow.getHardTimeout() != null) {
131 flowMod.setHardTimeout(flow.getHardTimeout());
133 flowMod.setHardTimeout(DEFAULT_HARD_TIMEOUT);
135 if (flow.getPriority() != null) {
136 flowMod.setPriority(flow.getPriority());
138 flowMod.setPriority(DEFAULT_PRIORITY);
140 if (flow.getBufferId() != null) {
141 flowMod.setBufferId(flow.getBufferId());
143 flowMod.setBufferId(DEFAULT_BUFFER_ID);
146 if (flow.getOutPort() != null) {
147 flowMod.setOutPort(new PortNumber(flow.getOutPort().longValue()));
149 flowMod.setOutPort(new PortNumber(DEFAULT_OUT_PORT));
151 if (flow.getOutGroup() != null) {
152 flowMod.setOutGroup(flow.getOutGroup());
154 flowMod.setOutGroup(DEFAULT_OUT_GROUP);
158 // convert and inject flowFlags
159 FlowFlagReactor.getInstance().convert(flow.getFlags(), version, flowMod);
161 // convert and inject match
162 MatchReactor.getInstance().convert(flow.getMatch(), version, flowMod);
164 if (flow.getInstructions() != null) {
165 flowMod.setInstructions(toInstructions(flow.getInstructions(), version));
167 flowMod.setVersion(version);
168 return flowMod.build();
171 private static List<Instructions> toInstructions(
172 org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions instructions,
174 List<Instructions> instructionsList = new ArrayList<>();
176 for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction instruction : instructions
178 InstructionsBuilder instructionBuilder = new InstructionsBuilder();
179 org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction curInstruction = instruction
181 if (curInstruction instanceof GoToTableCase) {
182 GoToTableCase goToTablecase = (GoToTableCase) curInstruction;
183 GoToTable goToTable = goToTablecase.getGoToTable();
185 .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.GotoTable.class);
186 TableIdInstructionBuilder tableBuilder = new TableIdInstructionBuilder();
187 tableBuilder.setTableId(goToTable.getTableId());
188 instructionBuilder.addAugmentation(TableIdInstruction.class, tableBuilder.build());
189 instructionsList.add(instructionBuilder.build());
192 else if (curInstruction instanceof WriteMetadataCase) {
193 WriteMetadataCase writeMetadatacase = (WriteMetadataCase) curInstruction;
194 WriteMetadata writeMetadata = writeMetadatacase.getWriteMetadata();
196 .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.WriteMetadata.class);
197 MetadataInstructionBuilder metadataBuilder = new MetadataInstructionBuilder();
198 metadataBuilder.setMetadata(ByteUtil.convertBigIntegerTo64Bit(writeMetadata.getMetadata()));
200 .setMetadataMask(ByteUtil.convertBigIntegerTo64Bit(writeMetadata.getMetadataMask()));
201 instructionBuilder.addAugmentation(MetadataInstruction.class, metadataBuilder.build());
202 instructionsList.add(instructionBuilder.build());
205 else if (curInstruction instanceof WriteActionsCase) {
206 WriteActionsCase writeActionscase = (WriteActionsCase) curInstruction;
207 WriteActions writeActions = writeActionscase.getWriteActions();
209 .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.WriteActions.class);
210 ActionsInstructionBuilder actionsInstructionBuilder = new ActionsInstructionBuilder();
211 actionsInstructionBuilder.setActionsList(ActionConvertor.getActionList(writeActions.getAction(),
213 instructionBuilder.addAugmentation(ActionsInstruction.class, actionsInstructionBuilder.build());
214 instructionsList.add(instructionBuilder.build());
217 else if (curInstruction instanceof ApplyActionsCase) {
218 ApplyActionsCase applyActionscase = (ApplyActionsCase) curInstruction;
219 ApplyActions applyActions = applyActionscase.getApplyActions();
221 .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.ApplyActions.class);
222 ActionsInstructionBuilder actionsInstructionBuilder = new ActionsInstructionBuilder();
223 actionsInstructionBuilder.setActionsList(ActionConvertor.getActionList(applyActions.getAction(),
225 instructionBuilder.addAugmentation(ActionsInstruction.class, actionsInstructionBuilder.build());
226 instructionsList.add(instructionBuilder.build());
229 else if (curInstruction instanceof ClearActionsCase) {
230 ClearActionsCase clearActionscase = (ClearActionsCase) curInstruction;
231 ClearActions clearActions = clearActionscase.getClearActions();
233 .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.ClearActions.class);
234 ActionsInstructionBuilder actionsInstructionBuilder = new ActionsInstructionBuilder();
235 actionsInstructionBuilder.setActionsList(ActionConvertor.getActionList(clearActions.getAction(),
237 instructionBuilder.addAugmentation(ActionsInstruction.class, actionsInstructionBuilder.build());
238 instructionsList.add(instructionBuilder.build());
241 else if (curInstruction instanceof MeterCase) {
242 MeterCase metercase = (MeterCase) curInstruction;
243 Meter meter = metercase.getMeter();
245 .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.Meter.class);
246 MeterIdInstructionBuilder meterBuilder = new MeterIdInstructionBuilder();
247 Long meterId = meter.getMeterId().getValue();
248 meterBuilder.setMeterId(meterId);
249 instructionBuilder.addAugmentation(MeterIdInstruction.class, meterBuilder.build());
250 instructionsList.add(instructionBuilder.build());
253 return instructionsList;