2 * Copyright (c) 2013 Pantheon Technologies s.r.o. 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.openflowjava.protocol.impl.serialization.factories;
11 import io.netty.buffer.ByteBuf;
13 import java.util.HashMap;
14 import java.util.List;
17 import org.opendaylight.openflowjava.protocol.impl.serialization.OFSerializer;
18 import org.opendaylight.openflowjava.protocol.impl.util.ActionsSerializer;
19 import org.opendaylight.openflowjava.protocol.impl.util.ByteBufUtils;
20 import org.opendaylight.openflowjava.protocol.impl.util.EncodeConstants;
21 import org.opendaylight.openflowjava.protocol.impl.util.InstructionsSerializer;
22 import org.opendaylight.openflowjava.protocol.impl.util.MatchSerializer;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ActionRelatedTableFeatureProperty;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ExperimenterRelatedTableFeatureProperty;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.InstructionRelatedTableFeatureProperty;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.NextTableRelatedTableFeatureProperty;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.OxmRelatedTableFeatureProperty;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.table.features.properties.container.table.feature.properties.NextTableIds;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.ActionsList;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.Instructions;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableConfig;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableFeaturesPropType;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.MatchEntries;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.MultipartRequestBody;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestAggregate;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestDesc;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestExperimenter;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestFlow;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroup;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupDesc;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupFeatures;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeter;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterConfig;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterFeatures;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestPortDesc;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestPortStats;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestQueue;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTable;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTableFeatures;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features.TableFeatures;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.TableFeatureProperties;
57 * Translates MultipartRequest messages
58 * @author timotej.kubas
59 * @author michal.polkorab
61 public class MultipartRequestInputFactory implements OFSerializer<MultipartRequestInput> {
62 private static final byte MESSAGE_TYPE = 18;
63 private static final int MESSAGE_LENGTH = 16;
64 private static final byte PADDING_IN_MULTIPART_REQUEST_MESSAGE = 4;
65 private static final byte TABLE_FEAT_HEADER_LENGTH = 4;
66 private static MultipartRequestInputFactory instance;
67 private static final byte INSTRUCTIONS_CODE = 0;
68 private static final byte INSTRUCTIONS_MISS_CODE = 1;
69 private static final byte NEXT_TABLE_CODE = 2;
70 private static final byte NEXT_TABLE_MISS_CODE = 3;
71 private static final byte WRITE_ACTIONS_CODE = 4;
72 private static final byte WRITE_ACTIONS_MISS_CODE = 5;
73 private static final byte APPLY_ACTIONS_CODE = 6;
74 private static final byte APPLY_ACTIONS_MISS_CODE = 7;
75 private static final byte MATCH_CODE = 8;
76 private static final byte WILDCARDS_CODE = 10;
77 private static final byte WRITE_SETFIELD_CODE = 12;
78 private static final byte WRITE_SETFIELD_MISS_CODE = 13;
79 private static final byte APPLY_SETFIELD_CODE = 14;
80 private static final byte APPLY_SETFIELD_MISS_CODE = 15;
81 private static final int EXPERIMENTER_CODE = 65534; // 0xFFFE
82 private static final int EXPERIMENTER_MISS_CODE = 65535; // 0xFFFF
83 private static final byte FLOW_BODY_LENGTH = 32;
84 private static final byte AGGREGATE_BODY_LENGTH = 32;
85 private static final byte PORT_STATS_BODY_LENGTH = 8;
86 private static final byte QUEUE_BODY_LENGTH = 8;
87 private static final byte GROUP_BODY_LENGTH = 8;
88 private static final byte METER_BODY_LENGTH = 8;
89 private static final byte METER_CONFIG_BODY_LENGTH = 8;
90 private static final byte EXPERIMENTER_BODY_LENGTH = 8;
91 private static final byte TABLE_FEATURES_LENGTH = 64;
92 private static final byte STRUCTURE_HEADER_LENGTH = 4;
93 private static final byte PADDING_IN_MULTIPART_REQUEST_FLOW_BODY_01 = 3;
94 private static final byte PADDING_IN_MULTIPART_REQUEST_FLOW_BODY_02 = 4;
95 private static final byte PADDING_IN_MULTIPART_REQUEST_AGREGGATE_BODY_01 = 3;
96 private static final byte PADDING_IN_MULTIPART_REQUEST_AGREGGATE_BODY_02 = 4;
97 private static final byte PADDING_IN_MULTIPART_REQUEST_PORTSTATS_BODY = 4;
98 private static final byte PADDING_IN_MULTIPART_REQUEST_GROUP_BODY = 4;
99 private static final byte PADDING_IN_MULTIPART_REQUEST_METER_BODY = 4;
100 private static final byte PADDING_IN_MULTIPART_REQUEST_METER_CONFIG_BODY = 4;
101 private static final byte PADDING_IN_MULTIPART_REQUEST_TABLE_FEATURES_BODY = 5;
105 private MultipartRequestInputFactory() {
110 * @return singleton factory
112 public static synchronized MultipartRequestInputFactory getInstance() {
113 if (instance == null) {
114 instance = new MultipartRequestInputFactory();
120 public void messageToBuffer(short version, ByteBuf out,
121 MultipartRequestInput message) {
122 ByteBufUtils.writeOFHeader(instance, message, out);
123 out.writeShort(message.getType().getIntValue());
124 out.writeShort(createMultipartRequestFlagsBitmask(message.getFlags()));
125 ByteBufUtils.padBuffer(PADDING_IN_MULTIPART_REQUEST_MESSAGE, out);
127 if (message.getMultipartRequestBody() instanceof MultipartRequestDesc ){
128 encodeDescBody(message.getMultipartRequestBody(), out);
129 } else if (message.getMultipartRequestBody() instanceof MultipartRequestFlow) {
130 encodeFlowBody(message.getMultipartRequestBody(), out);
131 } else if (message.getMultipartRequestBody() instanceof MultipartRequestAggregate) {
132 encodeAggregateBody(message.getMultipartRequestBody(), out);
133 } else if (message.getMultipartRequestBody() instanceof MultipartRequestTable) {
134 encodeTableBody(message.getMultipartRequestBody(), out);
135 } else if (message.getMultipartRequestBody() instanceof MultipartRequestPortStats) {
136 encodePortStatsBody(message.getMultipartRequestBody(), out);
137 } else if (message.getMultipartRequestBody() instanceof MultipartRequestQueue) {
138 encodeQueueBody(message.getMultipartRequestBody(), out);
139 } else if (message.getMultipartRequestBody() instanceof MultipartRequestGroup) {
140 encodeGroupStatsBody(message.getMultipartRequestBody(), out);
141 } else if (message.getMultipartRequestBody() instanceof MultipartRequestGroupDesc) {
142 encodeGroupDescBody(message.getMultipartRequestBody(), out);
143 } else if (message.getMultipartRequestBody() instanceof MultipartRequestGroupFeatures) {
144 encodeGroupFeaturesBody(message.getMultipartRequestBody(), out);
145 } else if (message.getMultipartRequestBody() instanceof MultipartRequestMeter) {
146 encodeMeterBody(message.getMultipartRequestBody(), out);
147 } else if (message.getMultipartRequestBody() instanceof MultipartRequestMeterConfig) {
148 encodeMeterConfigBody(message.getMultipartRequestBody(), out);
149 } else if (message.getMultipartRequestBody() instanceof MultipartRequestMeterFeatures) {
150 encodeMeterFeaturesBody(message.getMultipartRequestBody(), out);
151 } else if (message.getMultipartRequestBody() instanceof MultipartRequestTableFeatures) {
152 encodeTableFeaturesBody(message.getMultipartRequestBody(), out);
153 } else if (message.getMultipartRequestBody() instanceof MultipartRequestPortDesc) {
154 encodePortDescBody(message.getMultipartRequestBody(), out);
155 } else if (message.getMultipartRequestBody() instanceof MultipartRequestExperimenter) {
156 encodeExperimenterBody(message.getMultipartRequestBody(), out);
161 public int computeLength(MultipartRequestInput message) {
162 return MESSAGE_LENGTH + computeBodyLength(message);
165 public byte getMessageType() {
172 * @return length of MultipartRequestMessage
174 public int computeBodyLength(MultipartRequestInput message) {
176 MultipartType type = message.getType();
177 if (type.equals(MultipartType.OFPMPFLOW)) {
178 MultipartRequestFlow body = (MultipartRequestFlow) message.getMultipartRequestBody();
179 length += FLOW_BODY_LENGTH + MatchSerializer.computeMatchLength(body.getMatch());
180 } else if (type.equals(MultipartType.OFPMPAGGREGATE)) {
181 MultipartRequestAggregate body = (MultipartRequestAggregate) message.getMultipartRequestBody();
182 length += AGGREGATE_BODY_LENGTH + MatchSerializer.computeMatchLength(body.getMatch());
183 } else if (type.equals(MultipartType.OFPMPPORTSTATS)) {
184 length += PORT_STATS_BODY_LENGTH;
185 } else if (type.equals(MultipartType.OFPMPQUEUE)) {
186 length += QUEUE_BODY_LENGTH;
187 } else if (type.equals(MultipartType.OFPMPGROUP)) {
188 length += GROUP_BODY_LENGTH;
189 } else if (type.equals(MultipartType.OFPMPMETER)) {
190 length += METER_BODY_LENGTH;
191 } else if (type.equals(MultipartType.OFPMPMETERCONFIG)) {
192 length += METER_CONFIG_BODY_LENGTH;
193 } else if (type.equals(MultipartType.OFPMPTABLEFEATURES)) {
194 MultipartRequestTableFeatures body = (MultipartRequestTableFeatures) message.getMultipartRequestBody();
195 length += computeTableFeaturesLength(body);
196 } else if (type.equals(MultipartType.OFPMPEXPERIMENTER)) {
197 MultipartRequestExperimenter body = (MultipartRequestExperimenter) message.getMultipartRequestBody();
198 length += EXPERIMENTER_BODY_LENGTH;
199 if (body.getData() != null) {
200 length += body.getData().length;
206 private static int computeTableFeaturesLength(MultipartRequestTableFeatures body) {
208 if (body != null && body.getTableFeatures() != null) {
209 List<TableFeatures> tableFeatures = body.getTableFeatures();
210 for (TableFeatures feature : tableFeatures) {
211 length += TABLE_FEATURES_LENGTH;
212 List<TableFeatureProperties> featureProperties = feature.getTableFeatureProperties();
213 if (featureProperties != null) {
214 for (TableFeatureProperties featProp : featureProperties) {
215 length += TABLE_FEAT_HEADER_LENGTH;
216 if (featProp.getAugmentation(InstructionRelatedTableFeatureProperty.class) != null) {
217 InstructionRelatedTableFeatureProperty property =
218 featProp.getAugmentation(InstructionRelatedTableFeatureProperty.class);
219 length += property.getInstructions().size() * STRUCTURE_HEADER_LENGTH;
220 } else if (featProp.getAugmentation(NextTableRelatedTableFeatureProperty.class) != null) {
221 NextTableRelatedTableFeatureProperty property =
222 featProp.getAugmentation(NextTableRelatedTableFeatureProperty.class);
223 length += property.getNextTableIds().size();
224 } else if (featProp.getAugmentation(ActionRelatedTableFeatureProperty.class) != null) {
225 ActionRelatedTableFeatureProperty property =
226 featProp.getAugmentation(ActionRelatedTableFeatureProperty.class);
227 length += property.getActionsList().size() * STRUCTURE_HEADER_LENGTH;
228 } else if (featProp.getAugmentation(OxmRelatedTableFeatureProperty.class) != null) {
229 OxmRelatedTableFeatureProperty property =
230 featProp.getAugmentation(OxmRelatedTableFeatureProperty.class);
231 length += property.getMatchEntries().size() * STRUCTURE_HEADER_LENGTH;
232 } else if (featProp.getAugmentation(ExperimenterRelatedTableFeatureProperty.class) != null) {
233 ExperimenterRelatedTableFeatureProperty property =
234 featProp.getAugmentation(ExperimenterRelatedTableFeatureProperty.class);
235 length += 2 * (EncodeConstants.SIZE_OF_INT_IN_BYTES);
236 if (property.getData() != null) {
237 length += property.getData().length;
247 private static int createMultipartRequestFlagsBitmask(MultipartRequestFlags flags) {
248 int multipartRequestFlagsBitmask = 0;
249 Map<Integer, Boolean> multipartRequestFlagsMap = new HashMap<>();
250 multipartRequestFlagsMap.put(0, flags.isOFPMPFREQMORE());
252 multipartRequestFlagsBitmask = ByteBufUtils.fillBitMaskFromMap(multipartRequestFlagsMap);
253 return multipartRequestFlagsBitmask;
257 * @param multipartRequestBody
260 private void encodeDescBody(MultipartRequestBody multipartRequestBody,
262 // The body of MultiPartRequestDesc is empty
266 * @param multipartRequestBody
269 private void encodeTableBody(MultipartRequestBody multipartRequestBody,
271 // The body of MultiPartTable is empty
275 * @param multipartRequestBody
278 private void encodeGroupDescBody(MultipartRequestBody multipartRequestBody,
280 // The body of MultiPartRequestGroupDesc is empty
284 * @param multipartRequestBody
287 private void encodeGroupFeaturesBody(
288 MultipartRequestBody multipartRequestBody, ByteBuf out) {
289 // The body of MultiPartRequestGroupFeatures is empty
293 * @param multipartRequestBody
296 private void encodeMeterFeaturesBody(
297 MultipartRequestBody multipartRequestBody, ByteBuf out) {
298 // The body of MultiPartMeterFeatures is empty
302 * @param multipartRequestBody
305 private void encodePortDescBody(MultipartRequestBody multipartRequestBody,
307 // The body of MultiPartPortDesc is empty
310 private static void encodeFlowBody(MultipartRequestBody multipartRequestBody, ByteBuf output) {
311 MultipartRequestFlow flow = (MultipartRequestFlow) multipartRequestBody;
312 output.writeByte(flow.getTableId().byteValue());
313 ByteBufUtils.padBuffer(PADDING_IN_MULTIPART_REQUEST_FLOW_BODY_01, output);
314 output.writeInt(flow.getOutPort().intValue());
315 output.writeInt(flow.getOutGroup().intValue());
316 ByteBufUtils.padBuffer(PADDING_IN_MULTIPART_REQUEST_FLOW_BODY_02, output);
317 output.writeLong(flow.getCookie().longValue());
318 output.writeLong(flow.getCookieMask().longValue());
319 MatchSerializer.encodeMatch(flow.getMatch(), output);
322 private static void encodeAggregateBody(MultipartRequestBody multipartRequestBody, ByteBuf output) {
323 MultipartRequestAggregate aggregate = (MultipartRequestAggregate) multipartRequestBody;
324 output.writeByte(aggregate.getTableId().byteValue());
325 ByteBufUtils.padBuffer(PADDING_IN_MULTIPART_REQUEST_AGREGGATE_BODY_01, output);
326 output.writeInt(aggregate.getOutPort().intValue());
327 output.writeInt(aggregate.getOutGroup().intValue());
328 ByteBufUtils.padBuffer(PADDING_IN_MULTIPART_REQUEST_AGREGGATE_BODY_02, output);
329 output.writeLong(aggregate.getCookie().longValue());
330 output.writeLong(aggregate.getCookieMask().longValue());
331 MatchSerializer.encodeMatch(aggregate.getMatch(), output);
334 private static void encodePortStatsBody(MultipartRequestBody multipartRequestBody, ByteBuf output) {
335 MultipartRequestPortStats portstats = (MultipartRequestPortStats) multipartRequestBody;
336 output.writeInt(portstats.getPortNo().intValue());
337 ByteBufUtils.padBuffer(PADDING_IN_MULTIPART_REQUEST_PORTSTATS_BODY, output);
340 private static void encodeQueueBody(MultipartRequestBody multipartRequestBody, ByteBuf output) {
341 MultipartRequestQueue queue = (MultipartRequestQueue) multipartRequestBody;
342 output.writeInt(queue.getPortNo().intValue());
343 output.writeInt(queue.getQueueId().intValue());
346 private static void encodeGroupStatsBody(MultipartRequestBody multipartRequestBody, ByteBuf output) {
347 MultipartRequestGroup groupStats = (MultipartRequestGroup) multipartRequestBody;
348 output.writeInt(groupStats.getGroupId().getValue().intValue());
349 ByteBufUtils.padBuffer(PADDING_IN_MULTIPART_REQUEST_GROUP_BODY, output);
352 private static void encodeMeterBody(MultipartRequestBody multipartRequestBody, ByteBuf output) {
353 MultipartRequestMeter meter = (MultipartRequestMeter) multipartRequestBody;
354 output.writeInt(meter.getMeterId().getValue().intValue());
355 ByteBufUtils.padBuffer(PADDING_IN_MULTIPART_REQUEST_METER_BODY, output);
358 private static void encodeMeterConfigBody(MultipartRequestBody multipartRequestBody, ByteBuf output) {
359 MultipartRequestMeterConfig meterConfig = (MultipartRequestMeterConfig) multipartRequestBody;
360 output.writeInt(meterConfig.getMeterId().getValue().intValue());
361 ByteBufUtils.padBuffer(PADDING_IN_MULTIPART_REQUEST_METER_CONFIG_BODY, output);
364 private static void encodeExperimenterBody(MultipartRequestBody multipartRequestBody, ByteBuf output) {
365 MultipartRequestExperimenter experimenter = (MultipartRequestExperimenter) multipartRequestBody;
366 output.writeInt(experimenter.getExperimenter().intValue());
367 output.writeInt(experimenter.getExpType().intValue());
368 byte[] data = experimenter.getData();
370 output.writeBytes(data);
374 private static void encodeTableFeaturesBody(MultipartRequestBody multipartRequestBody, ByteBuf output) {
375 if (multipartRequestBody != null) {
376 MultipartRequestTableFeatures tableFeatures = (MultipartRequestTableFeatures) multipartRequestBody;
377 if(tableFeatures.getTableFeatures() != null) {
378 for (TableFeatures currTableFeature : tableFeatures.getTableFeatures()) {
379 output.writeByte(currTableFeature.getTableId());
380 ByteBufUtils.padBuffer(PADDING_IN_MULTIPART_REQUEST_TABLE_FEATURES_BODY, output);
381 output.writeBytes(currTableFeature.getName().getBytes());
382 ByteBufUtils.padBuffer((32 - currTableFeature.getName().getBytes().length), output);
383 output.writeLong(currTableFeature.getMetadataMatch().longValue());
384 output.writeLong(currTableFeature.getMetadataWrite().longValue());
385 output.writeInt(createTableConfigBitmask(currTableFeature.getConfig()));
386 output.writeInt(currTableFeature.getMaxEntries().intValue());
387 writeTableFeatureProperties(output, currTableFeature.getTableFeatureProperties());
393 private static void writeTableFeatureProperties(ByteBuf output, List<TableFeatureProperties> props) {
395 for (TableFeatureProperties property : props) {
396 TableFeaturesPropType type = property.getType();
397 if (type.equals(TableFeaturesPropType.OFPTFPTINSTRUCTIONS)) {
398 writeInstructionRelatedTableProperty(output, property, INSTRUCTIONS_CODE);
399 } else if (type.equals(TableFeaturesPropType.OFPTFPTINSTRUCTIONSMISS)) {
400 writeInstructionRelatedTableProperty(output, property, INSTRUCTIONS_MISS_CODE);
401 } else if (type.equals(TableFeaturesPropType.OFPTFPTNEXTTABLES)) {
402 writeNextTableRelatedTableProperty(output, property, NEXT_TABLE_CODE);
403 } else if (type.equals(TableFeaturesPropType.OFPTFPTNEXTTABLESMISS)) {
404 writeNextTableRelatedTableProperty(output, property, NEXT_TABLE_MISS_CODE);
405 } else if (type.equals(TableFeaturesPropType.OFPTFPTWRITEACTIONS)) {
406 writeActionsRelatedTableProperty(output, property, WRITE_ACTIONS_CODE);
407 } else if (type.equals(TableFeaturesPropType.OFPTFPTWRITEACTIONSMISS)) {
408 writeActionsRelatedTableProperty(output, property, WRITE_ACTIONS_MISS_CODE);
409 } else if (type.equals(TableFeaturesPropType.OFPTFPTAPPLYACTIONS)) {
410 writeActionsRelatedTableProperty(output, property, APPLY_ACTIONS_CODE);
411 } else if (type.equals(TableFeaturesPropType.OFPTFPTAPPLYACTIONSMISS)) {
412 writeActionsRelatedTableProperty(output, property, APPLY_ACTIONS_MISS_CODE);
413 } else if (type.equals(TableFeaturesPropType.OFPTFPTMATCH)) {
414 writeOxmRelatedTableProperty(output, property, MATCH_CODE);
415 } else if (type.equals(TableFeaturesPropType.OFPTFPTWILDCARDS)) {
416 writeOxmRelatedTableProperty(output, property, WILDCARDS_CODE);
417 } else if (type.equals(TableFeaturesPropType.OFPTFPTWRITESETFIELD)) {
418 writeOxmRelatedTableProperty(output, property, WRITE_SETFIELD_CODE);
419 } else if (type.equals(TableFeaturesPropType.OFPTFPTWRITESETFIELDMISS)) {
420 writeOxmRelatedTableProperty(output, property, WRITE_SETFIELD_MISS_CODE);
421 } else if (type.equals(TableFeaturesPropType.OFPTFPTAPPLYSETFIELD)) {
422 writeOxmRelatedTableProperty(output, property, APPLY_SETFIELD_CODE);
423 } else if (type.equals(TableFeaturesPropType.OFPTFPTAPPLYSETFIELDMISS)) {
424 writeOxmRelatedTableProperty(output, property, APPLY_SETFIELD_MISS_CODE);
425 } else if (type.equals(TableFeaturesPropType.OFPTFPTEXPERIMENTER)) {
426 writeExperimenterRelatedTableProperty(output, property, EXPERIMENTER_CODE);
427 } else if (type.equals(TableFeaturesPropType.OFPTFPTEXPERIMENTERMISS)) {
428 writeExperimenterRelatedTableProperty(output, property, EXPERIMENTER_MISS_CODE);
434 private static void writeInstructionRelatedTableProperty(ByteBuf output,
435 TableFeatureProperties property, byte code) {
436 output.writeShort(code);
437 List<Instructions> instructions = property.
438 getAugmentation(InstructionRelatedTableFeatureProperty.class).getInstructions();
439 int length = TABLE_FEAT_HEADER_LENGTH;
440 if (instructions != null) {
441 output.writeShort(InstructionsSerializer.computeInstructionsLength(instructions)
442 + TABLE_FEAT_HEADER_LENGTH);
443 InstructionsSerializer.encodeInstructions(instructions, output);
445 output.writeShort(length);
449 private static void writeNextTableRelatedTableProperty(ByteBuf output,
450 TableFeatureProperties property, byte code) {
451 output.writeShort(code);
452 List<NextTableIds> nextTableIds = property.
453 getAugmentation(NextTableRelatedTableFeatureProperty.class).getNextTableIds();
454 int length = TABLE_FEAT_HEADER_LENGTH;
455 if (nextTableIds != null) {
456 output.writeShort(length + nextTableIds.size());
457 for (NextTableIds next : nextTableIds) {
458 output.writeByte(next.getTableId());
461 output.writeShort(length);
465 private static void writeActionsRelatedTableProperty(ByteBuf output,
466 TableFeatureProperties property, byte code) {
467 output.writeShort(code);
468 List<ActionsList> actions = property.
469 getAugmentation(ActionRelatedTableFeatureProperty.class).getActionsList();
470 int length = TABLE_FEAT_HEADER_LENGTH;
471 if (actions != null) {
472 output.writeShort(ActionsSerializer.computeLengthOfActions(actions)
473 + TABLE_FEAT_HEADER_LENGTH);
474 ActionsSerializer.encodeActions(actions, output);
476 output.writeShort(length);
480 private static void writeOxmRelatedTableProperty(ByteBuf output,
481 TableFeatureProperties property, byte code) {
482 output.writeShort(code);
483 List<MatchEntries> entries = property.
484 getAugmentation(OxmRelatedTableFeatureProperty.class).getMatchEntries();
485 int length = TABLE_FEAT_HEADER_LENGTH;
486 if (entries != null) {
487 output.writeShort(MatchSerializer.computeMatchEntriesLength(entries)
488 + TABLE_FEAT_HEADER_LENGTH);
489 MatchSerializer.encodeMatchEntries(entries, output);
491 output.writeShort(length);
495 private static void writeExperimenterRelatedTableProperty(ByteBuf output,
496 TableFeatureProperties property, int code) {
497 output.writeShort(code);
498 ExperimenterRelatedTableFeatureProperty exp = property.
499 getAugmentation(ExperimenterRelatedTableFeatureProperty.class);
500 byte[] data = exp.getData();
501 int length = TABLE_FEAT_HEADER_LENGTH + 2 * (EncodeConstants.SIZE_OF_INT_IN_BYTES);
503 output.writeShort(length + data.length);
504 output.writeInt(exp.getExperimenter().intValue());
505 output.writeInt(exp.getExpType().intValue());
506 output.writeBytes(data);
508 output.writeShort(length);
509 output.writeInt(exp.getExperimenter().intValue());
510 output.writeInt(exp.getExpType().intValue());
514 private static int createTableConfigBitmask(TableConfig tableConfig) {
515 int tableConfigBitmask = 0;
516 Map<Integer, Boolean> tableConfigMap = new HashMap<>();
517 tableConfigMap.put(3, tableConfig.isOFPTCDEPRECATEDMASK());
519 tableConfigBitmask = ByteBufUtils.fillBitMaskFromMap(tableConfigMap);
520 return tableConfigBitmask;