254fb5893b55776bfdf5101470aacf9978d6a281
[openflowplugin.git] / openflowplugin / src / main / java / org / opendaylight / openflowplugin / openflow / md / core / sal / convertor / FlowConvertor.java
1 /**
2  * Copyright (c) 2013 Ericsson. and others.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.openflowplugin.openflow.md.core.sal.convertor;
10
11 import java.math.BigInteger;
12 import java.util.ArrayList;
13 import java.util.List;
14
15 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInput;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.UpdatedFlow;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ClearActionsCase;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.GoToTableCase;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.MeterCase;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteActionsCase;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteMetadataCase;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActions;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.clear.actions._case.ClearActions;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.go.to.table._case.GoToTable;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.meter._case.Meter;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.write.actions._case.WriteActions;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.write.metadata._case.WriteMetadata;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ActionsInstruction;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ActionsInstructionBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MetadataInstruction;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MetadataInstructionBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MeterIdInstruction;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MeterIdInstructionBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.TableIdInstruction;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.TableIdInstructionBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.Instructions;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.InstructionsBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowModCommand;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MatchTypeBase;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableId;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.OxmMatchType;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.MatchEntries;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInput;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInputBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.match.grouping.MatchBuilder;
51 import org.slf4j.Logger;
52 import org.slf4j.LoggerFactory;
53
54 /**
55  * Utility class for converting a MD-SAL Flow into the OF flow mod
56  */
57 public class FlowConvertor {
58     private static final Logger logger = LoggerFactory.getLogger(FlowConvertor.class);
59
60     // Default values for when things are null
61     private static final BigInteger DEFAULT_COOKIE = BigInteger.ZERO;
62     private static final BigInteger DEFAULT_COOKIE_MASK = BigInteger.ZERO;
63     private static final TableId DEFAULT_TABLE_ID = new TableId(new Long(0));
64     private static final Integer DEFAULT_IDLE_TIMEOUT = new Integer(5 * 60);
65     private static final Integer DEFAULT_HARD_TIMEOUT = new Integer(10 * 60);
66     private static final Integer DEFAULT_PRIORITY = Integer.parseInt("8000", 16);
67     private static final Long DEFAULT_BUFFER_ID = Long.parseLong("ffffffff", 16);
68     private static final Long OFPP_ANY = Long.parseLong("ffffffff", 16);
69     private static final Long DEFAULT_OUT_PORT = OFPP_ANY;
70     private static final Long OFPG_ANY = Long.parseLong("ffffffff", 16);
71     private static final Long DEFAULT_OUT_GROUP = OFPG_ANY;
72     private static final boolean DEFAULT_OFPFF_FLOW_REM = true;
73     private static final boolean DEFAULT_OFPFF_CHECK_OVERLAP = false;
74     private static final boolean DEFAULT_OFPFF_RESET_COUNTS = false;
75     private static final boolean DEFAULT_OFPFF_NO_PKT_COUNTS = false;
76     private static final boolean DEFAULT_OFPFF_NO_BYT_COUNTS = false;
77     private static final Class<? extends MatchTypeBase> DEFAULT_MATCH_TYPE = OxmMatchType.class;
78     private static final List<MatchEntries> DEFAULT_MATCH_ENTRIES = new ArrayList<MatchEntries>();
79
80     public static FlowModInput toFlowModInput(Flow flow, short version) {
81         FlowModInputBuilder flowMod = new FlowModInputBuilder();
82         if (flow.getCookie() != null) {
83             flowMod.setCookie(flow.getCookie());
84         } else {
85             flowMod.setCookie(DEFAULT_COOKIE);
86         }
87
88         if (flow.getCookieMask() != null) {
89             flowMod.setCookieMask(new BigInteger(flow.getCookieMask().toString()));
90         } else {
91             flowMod.setCookieMask(DEFAULT_COOKIE_MASK);
92         }
93
94         if (flow.getTableId() != null) {
95             flowMod.setTableId(new TableId(flow.getTableId().longValue()));
96         } else {
97             flowMod.setTableId(DEFAULT_TABLE_ID);
98         }
99
100         if (flow instanceof AddFlowInput) {
101             flowMod.setCommand(FlowModCommand.OFPFCADD);
102         } else if (flow instanceof RemoveFlowInput) {
103             if (flow.isStrict() != null && flow.isStrict()) {
104                 flowMod.setCommand(FlowModCommand.OFPFCDELETESTRICT);
105             } else {
106                 flowMod.setCommand(FlowModCommand.OFPFCDELETE);
107             }
108         } else if (flow instanceof UpdatedFlow) {
109             if (flow.isStrict() != null && flow.isStrict()) {
110                 flowMod.setCommand(FlowModCommand.OFPFCMODIFYSTRICT);
111             } else {
112                 flowMod.setCommand(FlowModCommand.OFPFCMODIFY);
113             }
114         }
115         if (flow.getIdleTimeout() != null) {
116             flowMod.setIdleTimeout(flow.getIdleTimeout());
117         } else {
118             flowMod.setIdleTimeout(DEFAULT_IDLE_TIMEOUT);
119         }
120         if (flow.getHardTimeout() != null) {
121             flowMod.setHardTimeout(flow.getHardTimeout());
122         } else {
123             flowMod.setHardTimeout(DEFAULT_HARD_TIMEOUT);
124         }
125         if (flow.getPriority() != null) {
126             flowMod.setPriority(flow.getPriority());
127         } else {
128             flowMod.setPriority(DEFAULT_PRIORITY);
129         }
130         if (flow.getBufferId() != null) {
131             flowMod.setBufferId(flow.getBufferId());
132         } else {
133             flowMod.setBufferId(DEFAULT_BUFFER_ID);
134         }
135
136         if (flow.getOutPort() != null) {
137             flowMod.setOutPort(new PortNumber(flow.getOutPort().longValue()));
138         } else {
139             flowMod.setOutPort(new PortNumber(DEFAULT_OUT_PORT));
140         }
141         if (flow.getOutGroup() != null) {
142             flowMod.setOutGroup(flow.getOutGroup());
143         } else {
144             flowMod.setOutGroup(DEFAULT_OUT_GROUP);
145         }
146
147         org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowModFlags flowModFlags = flow.getFlags();
148         org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowModFlags ofFlowModFlags = null;
149         if (flowModFlags != null) {
150             ofFlowModFlags = new org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowModFlags(
151                     flowModFlags.isCHECKOVERLAP(), flowModFlags.isNOBYTCOUNTS(), flowModFlags.isNOPKTCOUNTS(),
152                     flowModFlags.isRESETCOUNTS(), flowModFlags.isSENDFLOWREM());
153         } else {
154             ofFlowModFlags = new org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowModFlags(
155                     DEFAULT_OFPFF_CHECK_OVERLAP, DEFAULT_OFPFF_NO_BYT_COUNTS, DEFAULT_OFPFF_NO_PKT_COUNTS,
156                     DEFAULT_OFPFF_RESET_COUNTS, DEFAULT_OFPFF_FLOW_REM);
157         }
158         flowMod.setFlags(ofFlowModFlags);
159
160         MatchBuilder matchBuilder = new MatchBuilder();
161         if (flow.getMatch() != null) {
162             matchBuilder.setMatchEntries(MatchConvertor.toMatch(flow.getMatch()));
163         } else {
164             matchBuilder.setMatchEntries(DEFAULT_MATCH_ENTRIES);
165         }
166         matchBuilder.setType(DEFAULT_MATCH_TYPE);
167         flowMod.setMatch(matchBuilder.build());
168
169         if (flow.getInstructions() != null) {
170             flowMod.setInstructions(toInstructions(flow.getInstructions(), version));
171         }
172         flowMod.setVersion(version);
173         return flowMod.build();
174     }
175
176     private static List<Instructions> toInstructions(
177             org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions instructions,
178             short version) {
179         List<Instructions> instructionsList = new ArrayList<>();
180
181         for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction instruction : instructions
182                 .getInstruction()) {
183             InstructionsBuilder instructionBuilder = new InstructionsBuilder();
184             org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction curInstruction = instruction
185                     .getInstruction();
186             if (curInstruction instanceof GoToTableCase) {
187                 GoToTableCase goToTablecase = (GoToTableCase) curInstruction;
188                 GoToTable goToTable = goToTablecase.getGoToTable();
189                 instructionBuilder
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());
195             }
196
197             else if (curInstruction instanceof WriteMetadataCase) {
198                 WriteMetadataCase writeMetadatacase = (WriteMetadataCase) curInstruction;
199                 WriteMetadata writeMetadata = writeMetadatacase.getWriteMetadata();
200                 instructionBuilder
201                         .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.WriteMetadata.class);
202                 MetadataInstructionBuilder metadataBuilder = new MetadataInstructionBuilder();
203                 metadataBuilder.setMetadata(MatchConvertor.convertBigIntegerTo64Bit(writeMetadata.getMetadata()));
204                 metadataBuilder
205                         .setMetadataMask(MatchConvertor.convertBigIntegerTo64Bit(writeMetadata.getMetadataMask()));
206                 instructionBuilder.addAugmentation(MetadataInstruction.class, metadataBuilder.build());
207                 instructionsList.add(instructionBuilder.build());
208             }
209
210             else if (curInstruction instanceof WriteActionsCase) {
211                 WriteActionsCase writeActionscase = (WriteActionsCase) curInstruction;
212                 WriteActions writeActions = writeActionscase.getWriteActions();
213                 instructionBuilder
214                         .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.WriteActions.class);
215                 ActionsInstructionBuilder actionsInstructionBuilder = new ActionsInstructionBuilder();
216                 actionsInstructionBuilder.setActionsList(ActionConvertor.getActionList(writeActions.getAction(),
217                         version));
218                 instructionBuilder.addAugmentation(ActionsInstruction.class, actionsInstructionBuilder.build());
219                 instructionsList.add(instructionBuilder.build());
220             }
221
222             else if (curInstruction instanceof ApplyActionsCase) {
223                 ApplyActionsCase applyActionscase = (ApplyActionsCase) curInstruction;
224                 ApplyActions applyActions = applyActionscase.getApplyActions();
225                 instructionBuilder
226                         .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.ApplyActions.class);
227                 ActionsInstructionBuilder actionsInstructionBuilder = new ActionsInstructionBuilder();
228                 actionsInstructionBuilder.setActionsList(ActionConvertor.getActionList(applyActions.getAction(),
229                         version));
230                 instructionBuilder.addAugmentation(ActionsInstruction.class, actionsInstructionBuilder.build());
231                 instructionsList.add(instructionBuilder.build());
232             }
233
234             else if (curInstruction instanceof ClearActionsCase) {
235                 ClearActionsCase clearActionscase = (ClearActionsCase) curInstruction;
236                 ClearActions clearActions = clearActionscase.getClearActions();
237                 instructionBuilder
238                         .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.ClearActions.class);
239                 ActionsInstructionBuilder actionsInstructionBuilder = new ActionsInstructionBuilder();
240                 actionsInstructionBuilder.setActionsList(ActionConvertor.getActionList(clearActions.getAction(),
241                         version));
242                 instructionBuilder.addAugmentation(ActionsInstruction.class, actionsInstructionBuilder.build());
243                 instructionsList.add(instructionBuilder.build());
244             }
245
246             else if (curInstruction instanceof MeterCase) {
247                 MeterCase metercase = (MeterCase) curInstruction;
248                 Meter meter = metercase.getMeter();
249                 instructionBuilder
250                         .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.Meter.class);
251                 MeterIdInstructionBuilder meterBuilder = new MeterIdInstructionBuilder();
252                 Long meterId = meter.getMeterId().getValue();
253                 meterBuilder.setMeterId(meterId);
254                 instructionBuilder.addAugmentation(MeterIdInstruction.class, meterBuilder.build());
255                 instructionsList.add(instructionBuilder.build());
256             }
257         }
258         return instructionsList;
259     }
260 }