1 /* Copyright (C)2013 Pantheon Technologies, s.r.o. All rights reserved. */
\r
2 package org.opendaylight.openflowjava.protocol.impl.serialization.factories;
\r
4 import io.netty.buffer.ByteBuf;
\r
6 import java.util.HashMap;
\r
7 import java.util.List;
\r
8 import java.util.Map;
\r
10 import org.opendaylight.openflowjava.protocol.impl.serialization.OFSerializer;
\r
11 import org.opendaylight.openflowjava.protocol.impl.util.ActionsSerializer;
\r
12 import org.opendaylight.openflowjava.protocol.impl.util.ByteBufUtils;
\r
13 import org.opendaylight.openflowjava.protocol.impl.util.EncodeConstants;
\r
14 import org.opendaylight.openflowjava.protocol.impl.util.InstructionsSerializer;
\r
15 import org.opendaylight.openflowjava.protocol.impl.util.MatchSerializer;
\r
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ActionRelatedTableFeatureProperty;
\r
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ExperimenterRelatedTableFeatureProperty;
\r
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.InstructionRelatedTableFeatureProperty;
\r
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.NextTableRelatedTableFeatureProperty;
\r
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.OxmRelatedTableFeatureProperty;
\r
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.table.features.properties.container.table.feature.properties.NextTableIds;
\r
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.ActionsList;
\r
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.Instructions;
\r
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags;
\r
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
\r
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableConfig;
\r
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableFeaturesPropType;
\r
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.MatchEntries;
\r
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput;
\r
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.MultipartRequestBody;
\r
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestAggregate;
\r
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestDesc;
\r
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestExperimenter;
\r
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestFlow;
\r
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroup;
\r
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupDesc;
\r
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupFeatures;
\r
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeter;
\r
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterConfig;
\r
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterFeatures;
\r
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestPortDesc;
\r
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestPortStats;
\r
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestQueue;
\r
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTable;
\r
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTableFeatures;
\r
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features.TableFeatures;
\r
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.TableFeatureProperties;
\r
50 * Translates MultipartRequest messages
\r
51 * @author timotej.kubas
\r
52 * @author michal.polkorab
\r
54 public class MultipartRequestInputFactory implements OFSerializer<MultipartRequestInput> {
\r
55 private static final byte MESSAGE_TYPE = 18;
\r
56 private static final int MESSAGE_LENGTH = 16;
\r
57 private static final byte PADDING_IN_MULTIPART_REQUEST_MESSAGE = 4;
\r
58 private static final byte TABLE_FEAT_HEADER_LENGTH = 4;
\r
59 private static MultipartRequestInputFactory instance;
\r
60 private static final byte INSTRUCTIONS_CODE = 0;
\r
61 private static final byte INSTRUCTIONS_MISS_CODE = 1;
\r
62 private static final byte NEXT_TABLE_CODE = 2;
\r
63 private static final byte NEXT_TABLE_MISS_CODE = 3;
\r
64 private static final byte WRITE_ACTIONS_CODE = 4;
\r
65 private static final byte WRITE_ACTIONS_MISS_CODE = 5;
\r
66 private static final byte APPLY_ACTIONS_CODE = 6;
\r
67 private static final byte APPLY_ACTIONS_MISS_CODE = 7;
\r
68 private static final byte MATCH_CODE = 8;
\r
69 private static final byte WILDCARDS_CODE = 10;
\r
70 private static final byte WRITE_SETFIELD_CODE = 12;
\r
71 private static final byte WRITE_SETFIELD_MISS_CODE = 13;
\r
72 private static final byte APPLY_SETFIELD_CODE = 14;
\r
73 private static final byte APPLY_SETFIELD_MISS_CODE = 15;
\r
74 private static final int EXPERIMENTER_CODE = 65534; // 0xFFFE
\r
75 private static final int EXPERIMENTER_MISS_CODE = 65535; // 0xFFFF
\r
76 private static final byte FLOW_BODY_LENGTH = 32;
\r
77 private static final byte AGGREGATE_BODY_LENGTH = 32;
\r
78 private static final byte PORT_STATS_BODY_LENGTH = 8;
\r
79 private static final byte QUEUE_BODY_LENGTH = 8;
\r
80 private static final byte GROUP_BODY_LENGTH = 8;
\r
81 private static final byte METER_BODY_LENGTH = 8;
\r
82 private static final byte METER_CONFIG_BODY_LENGTH = 8;
\r
83 private static final byte EXPERIMENTER_BODY_LENGTH = 8;
\r
84 private static final byte TABLE_FEATURES_LENGTH = 64;
\r
85 private static final byte STRUCTURE_HEADER_LENGTH = 4;
\r
86 private static final byte PADDING_IN_MULTIPART_REQUEST_FLOW_BODY_01 = 3;
\r
87 private static final byte PADDING_IN_MULTIPART_REQUEST_FLOW_BODY_02 = 4;
\r
88 private static final byte PADDING_IN_MULTIPART_REQUEST_AGREGGATE_BODY_01 = 3;
\r
89 private static final byte PADDING_IN_MULTIPART_REQUEST_AGREGGATE_BODY_02 = 4;
\r
90 private static final byte PADDING_IN_MULTIPART_REQUEST_PORTSTATS_BODY = 4;
\r
91 private static final byte PADDING_IN_MULTIPART_REQUEST_GROUP_BODY = 4;
\r
92 private static final byte PADDING_IN_MULTIPART_REQUEST_METER_BODY = 4;
\r
93 private static final byte PADDING_IN_MULTIPART_REQUEST_METER_CONFIG_BODY = 4;
\r
94 private static final byte PADDING_IN_MULTIPART_REQUEST_TABLE_FEATURES_BODY = 5;
\r
98 private MultipartRequestInputFactory() {
\r
103 * @return singleton factory
\r
105 public static synchronized MultipartRequestInputFactory getInstance() {
\r
106 if (instance == null) {
\r
107 instance = new MultipartRequestInputFactory();
\r
113 public void messageToBuffer(short version, ByteBuf out,
\r
114 MultipartRequestInput message) {
\r
115 ByteBufUtils.writeOFHeader(instance, message, out);
\r
116 out.writeShort(message.getType().getIntValue());
\r
117 out.writeShort(createMultipartRequestFlagsBitmask(message.getFlags()));
\r
118 ByteBufUtils.padBuffer(PADDING_IN_MULTIPART_REQUEST_MESSAGE, out);
\r
120 if (message.getMultipartRequestBody() instanceof MultipartRequestDesc ){
\r
121 encodeDescBody(message.getMultipartRequestBody(), out);
\r
122 } else if (message.getMultipartRequestBody() instanceof MultipartRequestFlow) {
\r
123 encodeFlowBody(message.getMultipartRequestBody(), out);
\r
124 } else if (message.getMultipartRequestBody() instanceof MultipartRequestAggregate) {
\r
125 encodeAggregateBody(message.getMultipartRequestBody(), out);
\r
126 } else if (message.getMultipartRequestBody() instanceof MultipartRequestTable) {
\r
127 encodeTableBody(message.getMultipartRequestBody(), out);
\r
128 } else if (message.getMultipartRequestBody() instanceof MultipartRequestPortStats) {
\r
129 encodePortStatsBody(message.getMultipartRequestBody(), out);
\r
130 } else if (message.getMultipartRequestBody() instanceof MultipartRequestQueue) {
\r
131 encodeQueueBody(message.getMultipartRequestBody(), out);
\r
132 } else if (message.getMultipartRequestBody() instanceof MultipartRequestGroup) {
\r
133 encodeGroupStatsBody(message.getMultipartRequestBody(), out);
\r
134 } else if (message.getMultipartRequestBody() instanceof MultipartRequestGroupDesc) {
\r
135 encodeGroupDescBody(message.getMultipartRequestBody(), out);
\r
136 } else if (message.getMultipartRequestBody() instanceof MultipartRequestGroupFeatures) {
\r
137 encodeGroupFeaturesBody(message.getMultipartRequestBody(), out);
\r
138 } else if (message.getMultipartRequestBody() instanceof MultipartRequestMeter) {
\r
139 encodeMeterBody(message.getMultipartRequestBody(), out);
\r
140 } else if (message.getMultipartRequestBody() instanceof MultipartRequestMeterConfig) {
\r
141 encodeMeterConfigBody(message.getMultipartRequestBody(), out);
\r
142 } else if (message.getMultipartRequestBody() instanceof MultipartRequestMeterFeatures) {
\r
143 encodeMeterFeaturesBody(message.getMultipartRequestBody(), out);
\r
144 } else if (message.getMultipartRequestBody() instanceof MultipartRequestTableFeatures) {
\r
145 encodeTableFeaturesBody(message.getMultipartRequestBody(), out);
\r
146 } else if (message.getMultipartRequestBody() instanceof MultipartRequestPortDesc) {
\r
147 encodePortDescBody(message.getMultipartRequestBody(), out);
\r
148 } else if (message.getMultipartRequestBody() instanceof MultipartRequestExperimenter) {
\r
149 encodeExperimenterBody(message.getMultipartRequestBody(), out);
\r
154 public int computeLength(MultipartRequestInput message) {
\r
155 return MESSAGE_LENGTH + computeBodyLength(message);
\r
158 public byte getMessageType() {
\r
159 return MESSAGE_TYPE;
\r
165 * @return length of MultipartRequestMessage
\r
167 public int computeBodyLength(MultipartRequestInput message) {
\r
169 MultipartType type = message.getType();
\r
170 if (type.equals(MultipartType.OFPMPFLOW)) {
\r
171 MultipartRequestFlow body = (MultipartRequestFlow) message.getMultipartRequestBody();
\r
172 length += FLOW_BODY_LENGTH + MatchSerializer.computeMatchLength(body.getMatch());
\r
173 } else if (type.equals(MultipartType.OFPMPAGGREGATE)) {
\r
174 MultipartRequestAggregate body = (MultipartRequestAggregate) message.getMultipartRequestBody();
\r
175 length += AGGREGATE_BODY_LENGTH + MatchSerializer.computeMatchLength(body.getMatch());
\r
176 } else if (type.equals(MultipartType.OFPMPPORTSTATS)) {
\r
177 length += PORT_STATS_BODY_LENGTH;
\r
178 } else if (type.equals(MultipartType.OFPMPQUEUE)) {
\r
179 length += QUEUE_BODY_LENGTH;
\r
180 } else if (type.equals(MultipartType.OFPMPGROUP)) {
\r
181 length += GROUP_BODY_LENGTH;
\r
182 } else if (type.equals(MultipartType.OFPMPMETER)) {
\r
183 length += METER_BODY_LENGTH;
\r
184 } else if (type.equals(MultipartType.OFPMPMETERCONFIG)) {
\r
185 length += METER_CONFIG_BODY_LENGTH;
\r
186 } else if (type.equals(MultipartType.OFPMPTABLEFEATURES)) {
\r
187 MultipartRequestTableFeatures body = (MultipartRequestTableFeatures) message.getMultipartRequestBody();
\r
188 length += computeTableFeaturesLength(body);
\r
189 } else if (type.equals(MultipartType.OFPMPEXPERIMENTER)) {
\r
190 MultipartRequestExperimenter body = (MultipartRequestExperimenter) message.getMultipartRequestBody();
\r
191 length += EXPERIMENTER_BODY_LENGTH;
\r
192 if (body.getData() != null) {
\r
193 length += body.getData().length;
\r
199 private static int computeTableFeaturesLength(MultipartRequestTableFeatures body) {
\r
201 if (body != null && body.getTableFeatures() != null) {
\r
202 List<TableFeatures> tableFeatures = body.getTableFeatures();
\r
203 for (TableFeatures feature : tableFeatures) {
\r
204 length += TABLE_FEATURES_LENGTH;
\r
205 List<TableFeatureProperties> featureProperties = feature.getTableFeatureProperties();
\r
206 if (featureProperties != null) {
\r
207 for (TableFeatureProperties featProp : featureProperties) {
\r
208 length += TABLE_FEAT_HEADER_LENGTH;
\r
209 if (featProp.getAugmentation(InstructionRelatedTableFeatureProperty.class) != null) {
\r
210 InstructionRelatedTableFeatureProperty property =
\r
211 featProp.getAugmentation(InstructionRelatedTableFeatureProperty.class);
\r
212 length += property.getInstructions().size() * STRUCTURE_HEADER_LENGTH;
\r
213 } else if (featProp.getAugmentation(NextTableRelatedTableFeatureProperty.class) != null) {
\r
214 NextTableRelatedTableFeatureProperty property =
\r
215 featProp.getAugmentation(NextTableRelatedTableFeatureProperty.class);
\r
216 length += property.getNextTableIds().size();
\r
217 } else if (featProp.getAugmentation(ActionRelatedTableFeatureProperty.class) != null) {
\r
218 ActionRelatedTableFeatureProperty property =
\r
219 featProp.getAugmentation(ActionRelatedTableFeatureProperty.class);
\r
220 length += property.getActionsList().size() * STRUCTURE_HEADER_LENGTH;
\r
221 } else if (featProp.getAugmentation(OxmRelatedTableFeatureProperty.class) != null) {
\r
222 OxmRelatedTableFeatureProperty property =
\r
223 featProp.getAugmentation(OxmRelatedTableFeatureProperty.class);
\r
224 length += property.getMatchEntries().size() * STRUCTURE_HEADER_LENGTH;
\r
225 } else if (featProp.getAugmentation(ExperimenterRelatedTableFeatureProperty.class) != null) {
\r
226 ExperimenterRelatedTableFeatureProperty property =
\r
227 featProp.getAugmentation(ExperimenterRelatedTableFeatureProperty.class);
\r
228 length += 2 * (EncodeConstants.SIZE_OF_INT_IN_BYTES);
\r
229 if (property.getData() != null) {
\r
230 length += property.getData().length;
\r
240 private static int createMultipartRequestFlagsBitmask(MultipartRequestFlags flags) {
\r
241 int multipartRequestFlagsBitmask = 0;
\r
242 Map<Integer, Boolean> multipartRequestFlagsMap = new HashMap<>();
\r
243 multipartRequestFlagsMap.put(0, flags.isOFPMPFREQMORE());
\r
245 multipartRequestFlagsBitmask = ByteBufUtils.fillBitMaskFromMap(multipartRequestFlagsMap);
\r
246 return multipartRequestFlagsBitmask;
\r
250 * @param multipartRequestBody
\r
253 private void encodeDescBody(MultipartRequestBody multipartRequestBody,
\r
255 // The body of MultiPartRequestDesc is empty
\r
259 * @param multipartRequestBody
\r
262 private void encodeTableBody(MultipartRequestBody multipartRequestBody,
\r
264 // The body of MultiPartTable is empty
\r
268 * @param multipartRequestBody
\r
271 private void encodeGroupDescBody(MultipartRequestBody multipartRequestBody,
\r
273 // The body of MultiPartRequestGroupDesc is empty
\r
277 * @param multipartRequestBody
\r
280 private void encodeGroupFeaturesBody(
\r
281 MultipartRequestBody multipartRequestBody, ByteBuf out) {
\r
282 // The body of MultiPartRequestGroupFeatures is empty
\r
286 * @param multipartRequestBody
\r
289 private void encodeMeterFeaturesBody(
\r
290 MultipartRequestBody multipartRequestBody, ByteBuf out) {
\r
291 // The body of MultiPartMeterFeatures is empty
\r
295 * @param multipartRequestBody
\r
298 private void encodePortDescBody(MultipartRequestBody multipartRequestBody,
\r
300 // The body of MultiPartPortDesc is empty
\r
303 private static void encodeFlowBody(MultipartRequestBody multipartRequestBody, ByteBuf output) {
\r
304 MultipartRequestFlow flow = (MultipartRequestFlow) multipartRequestBody;
\r
305 output.writeByte(flow.getTableId().byteValue());
\r
306 ByteBufUtils.padBuffer(PADDING_IN_MULTIPART_REQUEST_FLOW_BODY_01, output);
\r
307 output.writeInt(flow.getOutPort().intValue());
\r
308 output.writeInt(flow.getOutGroup().intValue());
\r
309 ByteBufUtils.padBuffer(PADDING_IN_MULTIPART_REQUEST_FLOW_BODY_02, output);
\r
310 output.writeLong(flow.getCookie().longValue());
\r
311 output.writeLong(flow.getCookieMask().longValue());
\r
312 MatchSerializer.encodeMatch(flow.getMatch(), output);
\r
315 private static void encodeAggregateBody(MultipartRequestBody multipartRequestBody, ByteBuf output) {
\r
316 MultipartRequestAggregate aggregate = (MultipartRequestAggregate) multipartRequestBody;
\r
317 output.writeByte(aggregate.getTableId().byteValue());
\r
318 ByteBufUtils.padBuffer(PADDING_IN_MULTIPART_REQUEST_AGREGGATE_BODY_01, output);
\r
319 output.writeInt(aggregate.getOutPort().intValue());
\r
320 output.writeInt(aggregate.getOutGroup().intValue());
\r
321 ByteBufUtils.padBuffer(PADDING_IN_MULTIPART_REQUEST_AGREGGATE_BODY_02, output);
\r
322 output.writeLong(aggregate.getCookie().longValue());
\r
323 output.writeLong(aggregate.getCookieMask().longValue());
\r
324 MatchSerializer.encodeMatch(aggregate.getMatch(), output);
\r
327 private static void encodePortStatsBody(MultipartRequestBody multipartRequestBody, ByteBuf output) {
\r
328 MultipartRequestPortStats portstats = (MultipartRequestPortStats) multipartRequestBody;
\r
329 output.writeInt(portstats.getPortNo().intValue());
\r
330 ByteBufUtils.padBuffer(PADDING_IN_MULTIPART_REQUEST_PORTSTATS_BODY, output);
\r
333 private static void encodeQueueBody(MultipartRequestBody multipartRequestBody, ByteBuf output) {
\r
334 MultipartRequestQueue queue = (MultipartRequestQueue) multipartRequestBody;
\r
335 output.writeInt(queue.getPortNo().intValue());
\r
336 output.writeInt(queue.getQueueId().intValue());
\r
339 private static void encodeGroupStatsBody(MultipartRequestBody multipartRequestBody, ByteBuf output) {
\r
340 MultipartRequestGroup groupStats = (MultipartRequestGroup) multipartRequestBody;
\r
341 output.writeInt(groupStats.getGroupId().intValue());
\r
342 ByteBufUtils.padBuffer(PADDING_IN_MULTIPART_REQUEST_GROUP_BODY, output);
\r
345 private static void encodeMeterBody(MultipartRequestBody multipartRequestBody, ByteBuf output) {
\r
346 MultipartRequestMeter meter = (MultipartRequestMeter) multipartRequestBody;
\r
347 output.writeInt(meter.getMeterId().intValue());
\r
348 ByteBufUtils.padBuffer(PADDING_IN_MULTIPART_REQUEST_METER_BODY, output);
\r
351 private static void encodeMeterConfigBody(MultipartRequestBody multipartRequestBody, ByteBuf output) {
\r
352 MultipartRequestMeterConfig meterConfig = (MultipartRequestMeterConfig) multipartRequestBody;
\r
353 output.writeInt(meterConfig.getMeterId().intValue());
\r
354 ByteBufUtils.padBuffer(PADDING_IN_MULTIPART_REQUEST_METER_CONFIG_BODY, output);
\r
357 private static void encodeExperimenterBody(MultipartRequestBody multipartRequestBody, ByteBuf output) {
\r
358 MultipartRequestExperimenter experimenter = (MultipartRequestExperimenter) multipartRequestBody;
\r
359 output.writeInt(experimenter.getExperimenter().intValue());
\r
360 output.writeInt(experimenter.getExpType().intValue());
\r
361 byte[] data = experimenter.getData();
\r
362 if (data != null) {
\r
363 output.writeBytes(data);
\r
367 private static void encodeTableFeaturesBody(MultipartRequestBody multipartRequestBody, ByteBuf output) {
\r
368 if (multipartRequestBody != null) {
\r
369 MultipartRequestTableFeatures tableFeatures = (MultipartRequestTableFeatures) multipartRequestBody;
\r
370 if(tableFeatures.getTableFeatures() != null) {
\r
371 for (TableFeatures currTableFeature : tableFeatures.getTableFeatures()) {
\r
372 output.writeByte(currTableFeature.getTableId());
\r
373 ByteBufUtils.padBuffer(PADDING_IN_MULTIPART_REQUEST_TABLE_FEATURES_BODY, output);
\r
374 output.writeBytes(currTableFeature.getName().getBytes());
\r
375 ByteBufUtils.padBuffer((32 - currTableFeature.getName().getBytes().length), output);
\r
376 output.writeLong(currTableFeature.getMetadataMatch().longValue());
\r
377 output.writeLong(currTableFeature.getMetadataWrite().longValue());
\r
378 output.writeInt(createTableConfigBitmask(currTableFeature.getConfig()));
\r
379 output.writeInt(currTableFeature.getMaxEntries().intValue());
\r
380 writeTableFeatureProperties(output, currTableFeature.getTableFeatureProperties());
\r
386 private static void writeTableFeatureProperties(ByteBuf output, List<TableFeatureProperties> props) {
\r
387 if (props != null) {
\r
388 for (TableFeatureProperties property : props) {
\r
389 TableFeaturesPropType type = property.getType();
\r
390 if (type.equals(TableFeaturesPropType.OFPTFPTINSTRUCTIONS)) {
\r
391 writeInstructionRelatedTableProperty(output, property, INSTRUCTIONS_CODE);
\r
392 } else if (type.equals(TableFeaturesPropType.OFPTFPTINSTRUCTIONSMISS)) {
\r
393 writeInstructionRelatedTableProperty(output, property, INSTRUCTIONS_MISS_CODE);
\r
394 } else if (type.equals(TableFeaturesPropType.OFPTFPTNEXTTABLES)) {
\r
395 writeNextTableRelatedTableProperty(output, property, NEXT_TABLE_CODE);
\r
396 } else if (type.equals(TableFeaturesPropType.OFPTFPTNEXTTABLESMISS)) {
\r
397 writeNextTableRelatedTableProperty(output, property, NEXT_TABLE_MISS_CODE);
\r
398 } else if (type.equals(TableFeaturesPropType.OFPTFPTWRITEACTIONS)) {
\r
399 writeActionsRelatedTableProperty(output, property, WRITE_ACTIONS_CODE);
\r
400 } else if (type.equals(TableFeaturesPropType.OFPTFPTWRITEACTIONSMISS)) {
\r
401 writeActionsRelatedTableProperty(output, property, WRITE_ACTIONS_MISS_CODE);
\r
402 } else if (type.equals(TableFeaturesPropType.OFPTFPTAPPLYACTIONS)) {
\r
403 writeActionsRelatedTableProperty(output, property, APPLY_ACTIONS_CODE);
\r
404 } else if (type.equals(TableFeaturesPropType.OFPTFPTAPPLYACTIONSMISS)) {
\r
405 writeActionsRelatedTableProperty(output, property, APPLY_ACTIONS_MISS_CODE);
\r
406 } else if (type.equals(TableFeaturesPropType.OFPTFPTMATCH)) {
\r
407 writeOxmRelatedTableProperty(output, property, MATCH_CODE);
\r
408 } else if (type.equals(TableFeaturesPropType.OFPTFPTWILDCARDS)) {
\r
409 writeOxmRelatedTableProperty(output, property, WILDCARDS_CODE);
\r
410 } else if (type.equals(TableFeaturesPropType.OFPTFPTWRITESETFIELD)) {
\r
411 writeOxmRelatedTableProperty(output, property, WRITE_SETFIELD_CODE);
\r
412 } else if (type.equals(TableFeaturesPropType.OFPTFPTWRITESETFIELDMISS)) {
\r
413 writeOxmRelatedTableProperty(output, property, WRITE_SETFIELD_MISS_CODE);
\r
414 } else if (type.equals(TableFeaturesPropType.OFPTFPTAPPLYSETFIELD)) {
\r
415 writeOxmRelatedTableProperty(output, property, APPLY_SETFIELD_CODE);
\r
416 } else if (type.equals(TableFeaturesPropType.OFPTFPTAPPLYSETFIELDMISS)) {
\r
417 writeOxmRelatedTableProperty(output, property, APPLY_SETFIELD_MISS_CODE);
\r
418 } else if (type.equals(TableFeaturesPropType.OFPTFPTEXPERIMENTER)) {
\r
419 writeExperimenterRelatedTableProperty(output, property, EXPERIMENTER_CODE);
\r
420 } else if (type.equals(TableFeaturesPropType.OFPTFPTEXPERIMENTERMISS)) {
\r
421 writeExperimenterRelatedTableProperty(output, property, EXPERIMENTER_MISS_CODE);
\r
427 private static void writeInstructionRelatedTableProperty(ByteBuf output,
\r
428 TableFeatureProperties property, byte code) {
\r
429 output.writeShort(code);
\r
430 List<Instructions> instructions = property.
\r
431 getAugmentation(InstructionRelatedTableFeatureProperty.class).getInstructions();
\r
432 int length = TABLE_FEAT_HEADER_LENGTH;
\r
433 if (instructions != null) {
\r
434 output.writeShort(InstructionsSerializer.computeInstructionsLength(instructions)
\r
435 + TABLE_FEAT_HEADER_LENGTH);
\r
436 InstructionsSerializer.encodeInstructions(instructions, output);
\r
438 output.writeShort(length);
\r
442 private static void writeNextTableRelatedTableProperty(ByteBuf output,
\r
443 TableFeatureProperties property, byte code) {
\r
444 output.writeShort(code);
\r
445 List<NextTableIds> nextTableIds = property.
\r
446 getAugmentation(NextTableRelatedTableFeatureProperty.class).getNextTableIds();
\r
447 int length = TABLE_FEAT_HEADER_LENGTH;
\r
448 if (nextTableIds != null) {
\r
449 output.writeShort(length + nextTableIds.size());
\r
450 for (NextTableIds next : nextTableIds) {
\r
451 output.writeByte(next.getTableId());
\r
454 output.writeShort(length);
\r
458 private static void writeActionsRelatedTableProperty(ByteBuf output,
\r
459 TableFeatureProperties property, byte code) {
\r
460 output.writeShort(code);
\r
461 List<ActionsList> actions = property.
\r
462 getAugmentation(ActionRelatedTableFeatureProperty.class).getActionsList();
\r
463 int length = TABLE_FEAT_HEADER_LENGTH;
\r
464 if (actions != null) {
\r
465 output.writeShort(ActionsSerializer.computeLengthOfActions(actions)
\r
466 + TABLE_FEAT_HEADER_LENGTH);
\r
467 ActionsSerializer.encodeActions(actions, output);
\r
469 output.writeShort(length);
\r
473 private static void writeOxmRelatedTableProperty(ByteBuf output,
\r
474 TableFeatureProperties property, byte code) {
\r
475 output.writeShort(code);
\r
476 List<MatchEntries> entries = property.
\r
477 getAugmentation(OxmRelatedTableFeatureProperty.class).getMatchEntries();
\r
478 int length = TABLE_FEAT_HEADER_LENGTH;
\r
479 if (entries != null) {
\r
480 output.writeShort(MatchSerializer.computeMatchEntriesLength(entries)
\r
481 + TABLE_FEAT_HEADER_LENGTH);
\r
482 MatchSerializer.encodeMatchEntries(entries, output);
\r
484 output.writeShort(length);
\r
488 private static void writeExperimenterRelatedTableProperty(ByteBuf output,
\r
489 TableFeatureProperties property, int code) {
\r
490 output.writeShort(code);
\r
491 ExperimenterRelatedTableFeatureProperty exp = property.
\r
492 getAugmentation(ExperimenterRelatedTableFeatureProperty.class);
\r
493 byte[] data = exp.getData();
\r
494 int length = TABLE_FEAT_HEADER_LENGTH + 2 * (EncodeConstants.SIZE_OF_INT_IN_BYTES);
\r
495 if (data != null) {
\r
496 output.writeShort(length + data.length);
\r
497 output.writeInt(exp.getExperimenter().intValue());
\r
498 output.writeInt(exp.getExpType().intValue());
\r
499 output.writeBytes(data);
\r
501 output.writeShort(length);
\r
502 output.writeInt(exp.getExperimenter().intValue());
\r
503 output.writeInt(exp.getExpType().intValue());
\r
507 private static int createTableConfigBitmask(TableConfig tableConfig) {
\r
508 int tableConfigBitmask = 0;
\r
509 Map<Integer, Boolean> tableConfigMap = new HashMap<>();
\r
510 tableConfigMap.put(3, tableConfig.isOFPTCDEPRECATEDMASK());
\r
512 tableConfigBitmask = ByteBufUtils.fillBitMaskFromMap(tableConfigMap);
\r
513 return tableConfigBitmask;
\r