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.OFConstants;
16 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.flowflag.FlowFlagReactor;
17 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.match.MatchReactor;
18 import org.opendaylight.openflowplugin.openflow.md.util.ByteUtil;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.UpdatedFlow;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ClearActionsCase;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.GoToTableCase;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.MeterCase;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteActionsCase;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteMetadataCase;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActions;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.clear.actions._case.ClearActions;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.go.to.table._case.GoToTable;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.meter._case.Meter;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.write.actions._case.WriteActions;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.write.metadata._case.WriteMetadata;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ActionsInstruction;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ActionsInstructionBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MetadataInstruction;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MetadataInstructionBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MeterIdInstruction;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MeterIdInstructionBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.TableIdInstruction;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.TableIdInstructionBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.grouping.Action;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.grouping.Instruction;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.grouping.InstructionBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowModCommand;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MatchTypeBase;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableId;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.OxmMatchType;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.grouping.MatchEntries;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInputBuilder;
53 import org.slf4j.Logger;
54 import org.slf4j.LoggerFactory;
56 import com.google.common.base.Objects;
59 * Utility class for converting a MD-SAL Flow into the OF flow mod
61 public class FlowConvertor {
62 private static final Logger logger = LoggerFactory.getLogger(FlowConvertor.class);
64 // Default values for when things are null
65 private static final BigInteger DEFAULT_COOKIE = BigInteger.ZERO;
66 private static final BigInteger DEFAULT_COOKIE_MASK = BigInteger.ZERO;
67 private static final TableId DEFAULT_TABLE_ID = new TableId(0L);
68 private static final Integer DEFAULT_IDLE_TIMEOUT = 5 * 60;
69 private static final Integer DEFAULT_HARD_TIMEOUT = 10 * 60;
70 private static final Integer DEFAULT_PRIORITY = Integer.parseInt("8000", 16);
71 private static final Long DEFAULT_BUFFER_ID = Long.parseLong("ffffffff", 16);
72 private static final Long OFPP_ANY = Long.parseLong("ffffffff", 16);
73 private static final Long DEFAULT_OUT_PORT = OFPP_ANY;
74 private static final Long OFPG_ANY = Long.parseLong("ffffffff", 16);
75 private static final Long DEFAULT_OUT_GROUP = OFPG_ANY;
76 /** flow flag: remove */
77 public static final boolean DEFAULT_OFPFF_FLOW_REM = true;
78 /** flow flag: check overlap */
79 public static final boolean DEFAULT_OFPFF_CHECK_OVERLAP = false;
80 /** flow flag: reset counts */
81 public static final boolean DEFAULT_OFPFF_RESET_COUNTS = false;
82 /** flow flag: don't keep track of packet counts */
83 public static final boolean DEFAULT_OFPFF_NO_PKT_COUNTS = false;
84 /** flow flag: don't keep track of byte counts */
85 public static final boolean DEFAULT_OFPFF_NO_BYT_COUNTS = false;
86 /** flow flag: emergency [OFP-1.0] */
87 public static final boolean DEFAULT_OFPFF_EMERGENCY = false;
89 public static final Class<? extends MatchTypeBase> DEFAULT_MATCH_TYPE = OxmMatchType.class;
90 /** default match entries - empty */
91 public static final List<MatchEntries> DEFAULT_MATCH_ENTRIES = new ArrayList<MatchEntries>();
93 public static FlowModInputBuilder toFlowModInput(Flow flow, short version,BigInteger datapathid) {
94 FlowModInputBuilder flowMod = new FlowModInputBuilder();
95 if (flow.getCookie() != null) {
96 flowMod.setCookie(flow.getCookie().getValue());
98 flowMod.setCookie(DEFAULT_COOKIE);
101 if (flow.getCookieMask() != null) {
102 flowMod.setCookieMask(flow.getCookieMask().getValue());
104 flowMod.setCookieMask(DEFAULT_COOKIE_MASK);
107 if (flow.getTableId() != null) {
108 flowMod.setTableId(new TableId(flow.getTableId().longValue()));
110 flowMod.setTableId(DEFAULT_TABLE_ID);
113 if (flow instanceof AddFlowInput) {
114 flowMod.setCommand(FlowModCommand.OFPFCADD);
115 } else if (flow instanceof RemoveFlowInput) {
116 if (Objects.firstNonNull(flow.isStrict(), Boolean.FALSE)) {
117 flowMod.setCommand(FlowModCommand.OFPFCDELETESTRICT);
119 flowMod.setCommand(FlowModCommand.OFPFCDELETE);
121 } else if (flow instanceof UpdatedFlow) {
122 if (Objects.firstNonNull(flow.isStrict(), Boolean.FALSE)) {
123 flowMod.setCommand(FlowModCommand.OFPFCMODIFYSTRICT);
125 flowMod.setCommand(FlowModCommand.OFPFCMODIFY);
128 if (flow.getIdleTimeout() != null) {
129 flowMod.setIdleTimeout(flow.getIdleTimeout());
131 flowMod.setIdleTimeout(DEFAULT_IDLE_TIMEOUT);
133 if (flow.getHardTimeout() != null) {
134 flowMod.setHardTimeout(flow.getHardTimeout());
136 flowMod.setHardTimeout(DEFAULT_HARD_TIMEOUT);
138 if (flow.getPriority() != null) {
139 flowMod.setPriority(flow.getPriority());
141 flowMod.setPriority(DEFAULT_PRIORITY);
143 if (flow.getBufferId() != null) {
144 flowMod.setBufferId(flow.getBufferId());
146 flowMod.setBufferId(DEFAULT_BUFFER_ID);
149 if (flow.getOutPort() != null) {
150 flowMod.setOutPort(new PortNumber(flow.getOutPort().longValue()));
152 flowMod.setOutPort(new PortNumber(DEFAULT_OUT_PORT));
154 if (flow.getOutGroup() != null) {
155 flowMod.setOutGroup(flow.getOutGroup());
157 flowMod.setOutGroup(DEFAULT_OUT_GROUP);
161 // convert and inject flowFlags
162 FlowFlagReactor.getInstance().convert(flow.getFlags(), version, flowMod,datapathid);
164 // convert and inject match
165 MatchReactor.getInstance().convert(flow.getMatch(), version, flowMod,datapathid);
167 if (flow.getInstructions() != null) {
168 flowMod.setInstruction(toInstructions(flow.getInstructions(), version,datapathid));
169 flowMod.setAction(getActions(flow.getInstructions(), version,datapathid));
171 flowMod.setVersion(version);
176 private static List<Instruction> toInstructions(
177 org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions instructions,
178 short version,BigInteger datapathid) {
179 List<Instruction> instructionsList = new ArrayList<>();
181 for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction instruction : instructions
183 InstructionBuilder instructionBuilder = new InstructionBuilder();
184 org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction curInstruction = instruction
186 if (curInstruction instanceof GoToTableCase) {
187 GoToTableCase goToTablecase = (GoToTableCase) curInstruction;
188 GoToTable goToTable = goToTablecase.getGoToTable();
190 .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.GotoTable.class);
191 TableIdInstructionBuilder tableBuilder = new TableIdInstructionBuilder();
192 tableBuilder.setTableId(goToTable.getTableId());
193 instructionBuilder.addAugmentation(TableIdInstruction.class, tableBuilder.build());
194 instructionsList.add(instructionBuilder.build());
197 else if (curInstruction instanceof WriteMetadataCase) {
198 WriteMetadataCase writeMetadatacase = (WriteMetadataCase) curInstruction;
199 WriteMetadata writeMetadata = writeMetadatacase.getWriteMetadata();
201 .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.WriteMetadata.class);
202 MetadataInstructionBuilder metadataBuilder = new MetadataInstructionBuilder();
203 metadataBuilder.setMetadata(ByteUtil.convertBigIntegerToNBytes(writeMetadata.getMetadata(),
204 OFConstants.SIZE_OF_LONG_IN_BYTES));
206 .setMetadataMask(ByteUtil.convertBigIntegerToNBytes(writeMetadata.getMetadataMask(),
207 OFConstants.SIZE_OF_LONG_IN_BYTES));
208 instructionBuilder.addAugmentation(MetadataInstruction.class, metadataBuilder.build());
209 instructionsList.add(instructionBuilder.build());
212 else if (curInstruction instanceof WriteActionsCase) {
213 WriteActionsCase writeActionscase = (WriteActionsCase) curInstruction;
214 WriteActions writeActions = writeActionscase.getWriteActions();
216 .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.WriteActions.class);
217 ActionsInstructionBuilder actionsInstructionBuilder = new ActionsInstructionBuilder();
218 actionsInstructionBuilder.setAction(ActionConvertor.getActions(writeActions.getAction(),
219 version,datapathid));
220 instructionBuilder.addAugmentation(ActionsInstruction.class, actionsInstructionBuilder.build());
221 instructionsList.add(instructionBuilder.build());
224 else if (curInstruction instanceof ApplyActionsCase) {
225 ApplyActionsCase applyActionscase = (ApplyActionsCase) curInstruction;
226 ApplyActions applyActions = applyActionscase.getApplyActions();
228 .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.ApplyActions.class);
229 ActionsInstructionBuilder actionsInstructionBuilder = new ActionsInstructionBuilder();
230 actionsInstructionBuilder.setAction(ActionConvertor.getActions(applyActions.getAction(),
231 version,datapathid));
232 instructionBuilder.addAugmentation(ActionsInstruction.class, actionsInstructionBuilder.build());
233 instructionsList.add(instructionBuilder.build());
236 else if (curInstruction instanceof ClearActionsCase) {
237 ClearActionsCase clearActionscase = (ClearActionsCase) curInstruction;
238 ClearActions clearActions = clearActionscase.getClearActions();
240 .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.ClearActions.class);
241 instructionsList.add(instructionBuilder.build());
244 else if (curInstruction instanceof MeterCase) {
245 MeterCase metercase = (MeterCase) curInstruction;
246 Meter meter = metercase.getMeter();
248 .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.Meter.class);
249 MeterIdInstructionBuilder meterBuilder = new MeterIdInstructionBuilder();
250 Long meterId = meter.getMeterId().getValue();
251 meterBuilder.setMeterId(meterId);
252 instructionBuilder.addAugmentation(MeterIdInstruction.class, meterBuilder.build());
253 instructionsList.add(instructionBuilder.build());
256 return instructionsList;
259 private static List<Action> getActions(
260 org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions instructions,
261 short version,BigInteger datapathid) {
263 for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction instruction : instructions
265 org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction curInstruction = instruction
268 if (curInstruction instanceof ApplyActionsCase) {
269 ApplyActionsCase applyActionscase = (ApplyActionsCase) curInstruction;
270 ApplyActions applyActions = applyActionscase.getApplyActions();
271 return ActionConvertor.getActions(applyActions.getAction(), version,datapathid);