Merge remote-tracking branch 'origin/master' into of14
diff --git a/Makefile b/Makefile
index 018db0b..5f3d8e5 100644
--- a/Makefile
+++ b/Makefile
@@ -131,6 +131,7 @@
PYTHONPATH=${LOXI_OUTPUT_DIR}/pyloxi:. python py_gen/tests/of11.py
PYTHONPATH=${LOXI_OUTPUT_DIR}/pyloxi:. python py_gen/tests/of12.py
PYTHONPATH=${LOXI_OUTPUT_DIR}/pyloxi:. python py_gen/tests/of13.py
+ PYTHONPATH=${LOXI_OUTPUT_DIR}/pyloxi:. python py_gen/tests/of14.py
check-c: c
make -j4 -C ${LOXI_OUTPUT_DIR}/locitest
diff --git a/cmdline.py b/cmdline.py
index 6395fff..de7070a 100644
--- a/cmdline.py
+++ b/cmdline.py
@@ -33,7 +33,7 @@
# The default configuration dictionary for LOXI code generation
options_default = {
"lang" : "c",
- "version-list" : "1.0 1.1 1.2 1.3",
+ "version-list" : "1.0 1.1 1.2 1.3 1.4",
"install-dir" : "loxi_output",
}
diff --git a/java_gen/java_model.py b/java_gen/java_model.py
index 8726632..fa2199c 100644
--- a/java_gen/java_model.py
+++ b/java_gen/java_model.py
@@ -815,7 +815,7 @@
entry = enum.entry_by_version_value(self.msg.version, self.value)
return "%s.%s" % ( enum.name, entry.name)
except KeyError, e:
- logger.debug("No enum found", e)
+ logger.debug("No enum found for type %s version %s value %s", java_type, self.msg.version, self.value)
return self.value
@property
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/OFVersion.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/OFVersion.java
index 6f54e5f..0c54fdc 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/OFVersion.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/OFVersion.java
@@ -1,7 +1,7 @@
package org.projectfloodlight.openflow.protocol;
public enum OFVersion {
- OF_10(1), OF_11(2), OF_12(3), OF_13(4);
+ OF_10(1), OF_11(2), OF_12(3), OF_13(4), OF_14(5);
public final int wireVersion;
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/ver14/ChannelUtilsVer14.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/ver14/ChannelUtilsVer14.java
new file mode 100644
index 0000000..c893cab
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/ver14/ChannelUtilsVer14.java
@@ -0,0 +1,26 @@
+package org.projectfloodlight.openflow.protocol.ver14;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.projectfloodlight.openflow.exceptions.OFParseError;
+import org.projectfloodlight.openflow.protocol.OFMatchBmap;
+import org.projectfloodlight.openflow.protocol.match.Match;
+
+/**
+ * Collection of helper functions for reading and writing into ChannelBuffers
+ *
+ * @author capveg
+ */
+
+public class ChannelUtilsVer14 {
+ public static Match readOFMatch(final ChannelBuffer bb) throws OFParseError {
+ return OFMatchV3Ver14.READER.readFrom(bb);
+ }
+
+ public static OFMatchBmap readOFMatchBmap(ChannelBuffer bb) {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ public static void writeOFMatchBmap(ChannelBuffer bb, OFMatchBmap match) {
+ throw new UnsupportedOperationException("not implemented");
+ }
+}
diff --git a/java_gen/templates/custom/OFMatchV3.Builder.java b/java_gen/templates/custom/OFMatchV3.Builder.java
new file mode 100644
index 0000000..54b35ba
--- /dev/null
+++ b/java_gen/templates/custom/OFMatchV3.Builder.java
@@ -0,0 +1,106 @@
+
+ private OFOxmList.Builder oxmListBuilder;
+
+ private void initBuilder() {
+ if (oxmListBuilder != null)
+ return;
+ oxmListBuilder = new OFOxmList.Builder();
+ }
+
+ private void updateOxmList() {
+ this.oxmList = this.oxmListBuilder.build();
+ this.oxmListSet = true;
+ }
+
+ private <F extends OFValueType<F>> OFOxm<F> getOxm(MatchField<F> field) {
+//:: if has_parent:
+ return this.oxmListSet ? this.oxmList.get(field) : parentMessage.oxmList.get(field);
+//:: else:
+ return this.oxmListSet ? this.oxmList.get(field) : null;
+//:: #endif
+ }
+
+ @Override
+ public <F extends OFValueType<F>> F get(MatchField<F> field)
+ throws UnsupportedOperationException {
+ OFOxm<F> value = getOxm(field);
+ if (value == null)
+ return null;
+ return value.getValue();
+ }
+
+ @Override
+ public <F extends OFValueType<F>> Masked<F> getMasked(MatchField<F> field)
+ throws UnsupportedOperationException {
+ OFOxm<F> value = getOxm(field);
+ if (value == null || !value.isMasked())
+ return null;
+ // TODO: If changing OXMs to extend Masked, then use it here
+ return Masked.of(value.getValue(), value.getMask());
+ }
+
+ @Override
+ public boolean supports(MatchField<?> field) {
+ return supportsField(field);
+ }
+
+ @Override
+ public boolean supportsMasked(MatchField<?> field) {
+ return supportsField(field);
+ }
+
+ @Override
+ public boolean isExact(MatchField<?> field) {
+ OFOxm<?> value = getOxm(field);
+ return (value != null && !value.isMasked());
+ }
+
+ @Override
+ public boolean isFullyWildcarded(MatchField<?> field) {
+ OFOxm<?> value = getOxm(field);
+ return (value == null);
+ }
+
+ @Override
+ public boolean isPartiallyMasked(MatchField<?> field) {
+ OFOxm<?> value = getOxm(field);
+ return (value != null && value.isMasked());
+ }
+
+ @Override
+ public <F extends OFValueType<F>> Match.Builder setExact(
+ MatchField<F> field, F value) {
+ initBuilder();
+ OFOxm<F> oxm = OFFactories.getFactory(OFVersion.${version.constant_version}).oxms().fromValue(value, field);
+ this.oxmListBuilder.set(oxm);
+ updateOxmList();
+ return this;
+ }
+
+ @Override
+ public <F extends OFValueType<F>> Match.Builder setMasked(
+ MatchField<F> field, F value, F mask) {
+ initBuilder();
+ OFOxm<F> oxm = OFFactories.getFactory(OFVersion.${version.constant_version}).oxms().fromValueAndMask(value, mask, field);
+ this.oxmListBuilder.set(oxm);
+ updateOxmList();
+ return this;
+ }
+
+ @Override
+ public <F extends OFValueType<F>> Match.Builder setMasked(
+ MatchField<F> field, Masked<F> valueWithMask) {
+ initBuilder();
+ OFOxm<F> oxm = OFFactories.getFactory(OFVersion.${version.constant_version}).oxms().fromMasked(valueWithMask, field);
+ this.oxmListBuilder.set(oxm);
+ updateOxmList();
+ return this;
+ }
+
+ @Override
+ public <F extends OFValueType<F>> Match.Builder wildcard(MatchField<F> field) {
+ initBuilder();
+ this.oxmListBuilder.unset(field);
+ updateOxmList();
+ return this;
+ }
diff --git a/java_gen/templates/custom/OFMatchV3.java b/java_gen/templates/custom/OFMatchV3.java
new file mode 100644
index 0000000..799135c
--- /dev/null
+++ b/java_gen/templates/custom/OFMatchV3.java
@@ -0,0 +1,112 @@
+//:: from generic_utils import OrderedSet
+//:: from java_gen.java_model import model
+ @Override
+ public <F extends OFValueType<F>> F get(MatchField<F> field)
+ throws UnsupportedOperationException {
+ if (!supports(field))
+ throw new UnsupportedOperationException("${msg.name} does not support matching on field " + field.getName());
+
+ OFOxm<F> oxm = this.oxmList.get(field);
+
+ if (oxm == null || !field.arePrerequisitesOK(this))
+ return null;
+
+ return oxm.getValue();
+ }
+
+ @Override
+ public <F extends OFValueType<F>> Masked<F> getMasked(MatchField<F> field)
+ throws UnsupportedOperationException {
+ if (!supportsMasked(field))
+ throw new UnsupportedOperationException("${msg.name} does not support masked matching on field " + field.getName());
+
+ OFOxm<F> oxm = this.oxmList.get(field);
+
+ if (oxm == null || !field.arePrerequisitesOK(this))
+ return null;
+
+ if (oxm.getMask() == null)
+ return null;
+
+ // TODO: Make OfOxm extend Masked and just return the OXM?
+ return Masked.of(oxm.getValue(), oxm.getMask());
+ }
+
+ private static boolean supportsField(MatchField<?> field) {
+ switch (field.id) {
+ //:: for id_constant in sorted(set(id_constant for _, id_constant, _ in model.oxm_map.values())):
+ case ${id_constant}:
+ //:: #endfor
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ @Override
+ public boolean supports(MatchField<?> field) {
+ return supportsField(field);
+ }
+
+ @Override
+ public boolean supportsMasked(MatchField<?> field) {
+ return supportsField(field);
+ }
+
+ @Override
+ public boolean isExact(MatchField<?> field) {
+ if (!supports(field))
+ throw new UnsupportedOperationException("${msg.name} does not support matching on field " + field.getName());
+
+ OFOxm<?> oxm = this.oxmList.get(field);
+
+ return oxm != null && !oxm.isMasked();
+ }
+
+ @Override
+ public boolean isFullyWildcarded(MatchField<?> field) {
+ if (!supports(field))
+ throw new UnsupportedOperationException("${msg.name} does not support matching on field " + field.getName());
+
+ OFOxm<?> oxm = this.oxmList.get(field);
+
+ return oxm == null;
+ }
+
+ @Override
+ public boolean isPartiallyMasked(MatchField<?> field) {
+ if (!supports(field))
+ throw new UnsupportedOperationException("${msg.name} does not support matching on field " + field.getName());
+
+ OFOxm<?> oxm = this.oxmList.get(field);
+
+ return oxm != null && oxm.isMasked();
+ }
+
+ private class MatchFieldIterator extends AbstractIterator<MatchField<?>> {
+ private Iterator<OFOxm<?>> oxmIterator;
+
+ MatchFieldIterator() {
+ oxmIterator = oxmList.iterator();
+ }
+
+ @Override
+ protected MatchField<?> computeNext() {
+ while(oxmIterator.hasNext()) {
+ OFOxm<?> oxm = oxmIterator.next();
+ if(oxm.getMatchField().arePrerequisitesOK(${msg.name}.this))
+ return oxm.getMatchField();
+ }
+ endOfData();
+ return null;
+ }
+ }
+
+ @Override
+ public Iterable<MatchField<?>> getMatchFields() {
+ return new Iterable<MatchField<?>>() {
+ public Iterator<MatchField<?>> iterator() {
+ return new MatchFieldIterator();
+ }
+ };
+ }
diff --git a/java_gen/templates/custom/OFMatchV3Ver12.Builder.java b/java_gen/templates/custom/OFMatchV3Ver12.Builder.java
index 3fae367..ae2ecaa 100644
--- a/java_gen/templates/custom/OFMatchV3Ver12.Builder.java
+++ b/java_gen/templates/custom/OFMatchV3Ver12.Builder.java
@@ -1,106 +1 @@
-
- private OFOxmList.Builder oxmListBuilder;
-
- private synchronized void initBuilder() {
- if (oxmListBuilder != null)
- return;
- oxmListBuilder = new OFOxmList.Builder();
- }
-
- private synchronized void updateOxmList() {
- this.oxmList = this.oxmListBuilder.build();
- this.oxmListSet = true;
- }
-
- private <F extends OFValueType<F>> OFOxm<F> getOxm(MatchField<F> field) {
-//:: if has_parent:
- return this.oxmListSet ? this.oxmList.get(field) : parentMessage.oxmList.get(field);
-//:: else:
- return this.oxmListSet ? this.oxmList.get(field) : null;
-//:: #endif
- }
-
- @Override
- public synchronized <F extends OFValueType<F>> F get(MatchField<F> field)
- throws UnsupportedOperationException {
- OFOxm<F> value = getOxm(field);
- if (value == null)
- return null;
- return value.getValue();
- }
-
- @Override
- public synchronized <F extends OFValueType<F>> Masked<F> getMasked(MatchField<F> field)
- throws UnsupportedOperationException {
- OFOxm<F> value = getOxm(field);
- if (value == null || !value.isMasked())
- return null;
- // TODO: If changing OXMs to extend Masked, then use it here
- return Masked.of(value.getValue(), value.getMask());
- }
-
- @Override
- public boolean supports(MatchField<?> field) {
- return supportsField(field);
- }
-
- @Override
- public boolean supportsMasked(MatchField<?> field) {
- return supportsField(field);
- }
-
- @Override
- public synchronized boolean isExact(MatchField<?> field) {
- OFOxm<?> value = getOxm(field);
- return (value != null && !value.isMasked());
- }
-
- @Override
- public synchronized boolean isFullyWildcarded(MatchField<?> field) {
- OFOxm<?> value = getOxm(field);
- return (value == null);
- }
-
- @Override
- public synchronized boolean isPartiallyMasked(MatchField<?> field) {
- OFOxm<?> value = getOxm(field);
- return (value != null && value.isMasked());
- }
-
- @Override
- public synchronized <F extends OFValueType<F>> Match.Builder setExact(
- MatchField<F> field, F value) {
- initBuilder();
- OFOxm<F> oxm = OFFactories.getFactory(OFVersion.OF_13).oxms().fromValue(value, field);
- this.oxmListBuilder.set(oxm);
- updateOxmList();
- return this;
- }
-
- @Override
- public synchronized <F extends OFValueType<F>> Match.Builder setMasked(
- MatchField<F> field, F value, F mask) {
- initBuilder();
- OFOxm<F> oxm = OFFactories.getFactory(OFVersion.OF_13).oxms().fromValueAndMask(value, mask, field);
- this.oxmListBuilder.set(oxm);
- updateOxmList();
- return this;
- }
-
- @Override
- public synchronized <F extends OFValueType<F>> Match.Builder setMasked(
- MatchField<F> field, Masked<F> valueWithMask) {
- initBuilder();
- OFOxm<F> oxm = OFFactories.getFactory(OFVersion.OF_13).oxms().fromMasked(valueWithMask, field);
- this.oxmListBuilder.set(oxm);
- updateOxmList();
- return this;
- }
-
- @Override
- public synchronized <F extends OFValueType<F>> Match.Builder wildcard(MatchField<F> field) {
- initBuilder();
- this.oxmListBuilder.unset(field);
- updateOxmList();
- return this;
- }
+//:: include("custom/OFMatchV3.Builder.java", msg=msg, version=version, has_parent=False)
diff --git a/java_gen/templates/custom/OFMatchV3Ver12.java b/java_gen/templates/custom/OFMatchV3Ver12.java
index 81092c1..225b0dc 100644
--- a/java_gen/templates/custom/OFMatchV3Ver12.java
+++ b/java_gen/templates/custom/OFMatchV3Ver12.java
@@ -1,114 +1 @@
-
- @Override
- public <F extends OFValueType<F>> F get(MatchField<F> field)
- throws UnsupportedOperationException {
- if (!supports(field))
- throw new UnsupportedOperationException("OFMatchV3Ver13 does not support matching on field " + field.getName());
-
- OFOxm<F> oxm = this.oxmList.get(field);
-
- if (oxm == null || !field.arePrerequisitesOK(this))
- return null;
-
- return oxm.getValue();
- }
-
- @Override
- public <F extends OFValueType<F>> Masked<F> getMasked(MatchField<F> field)
- throws UnsupportedOperationException {
- if (!supportsMasked(field))
- throw new UnsupportedOperationException("OFMatchV3Ver13 does not support masked matching on field " + field.getName());
-
- OFOxm<F> oxm = this.oxmList.get(field);
-
- if (oxm == null || !field.arePrerequisitesOK(this))
- return null;
-
- if (oxm.getMask() == null)
- return null;
-
- // TODO: Make OfOxm extend Masked and just return the OXM?
- return Masked.of(oxm.getValue(), oxm.getMask());
- }
-
- private static boolean supportsField(MatchField<?> field) {
- switch (field.id) {
- case IN_PORT:
- case IN_PHY_PORT:
- case METADATA:
- case ETH_DST:
- case ETH_SRC:
- case ETH_TYPE:
- case VLAN_VID:
- case VLAN_PCP:
- case IP_DSCP:
- case IP_ECN:
- case IP_PROTO:
- case IPV4_SRC:
- case IPV4_DST:
- case TCP_SRC:
- case TCP_DST:
- case UDP_SRC:
- case UDP_DST:
- case SCTP_SRC:
- case SCTP_DST:
- case ICMPV4_TYPE:
- case ICMPV4_CODE:
- case ARP_OP:
- case ARP_SPA:
- case ARP_TPA:
- case ARP_SHA:
- case ARP_THA:
- case IPV6_SRC:
- case IPV6_DST:
- case IPV6_FLABEL:
- return true;
- default:
- return false;
- }
- }
-
- @Override
- public boolean supports(MatchField<?> field) {
- return supportsField(field);
- }
-
- @Override
- public boolean supportsMasked(MatchField<?> field) {
- return supportsField(field);
- }
-
- @Override
- public boolean isExact(MatchField<?> field) {
- if (!supports(field))
- throw new UnsupportedOperationException("OFMatchV3Ver13 does not support matching on field " + field.getName());
-
- OFOxm<?> oxm = this.oxmList.get(field);
-
- return oxm != null && !oxm.isMasked();
- }
-
- @Override
- public boolean isFullyWildcarded(MatchField<?> field) {
- if (!supports(field))
- throw new UnsupportedOperationException("OFMatchV3Ver13 does not support matching on field " + field.getName());
-
- OFOxm<?> oxm = this.oxmList.get(field);
-
- return oxm == null;
- }
-
- @Override
- public boolean isPartiallyMasked(MatchField<?> field) {
- if (!supports(field))
- throw new UnsupportedOperationException("OFMatchV3Ver13 does not support matching on field " + field.getName());
-
- OFOxm<?> oxm = this.oxmList.get(field);
-
- return oxm != null && oxm.isMasked();
- }
-
- @Override
- public Iterable<MatchField<?>> getMatchFields() {
- throw new UnsupportedOperationException();
- }
+//:: include("custom/OFMatchV3.java", msg=msg, has_parent=False)
diff --git a/java_gen/templates/custom/OFMatchV3Ver12_toString.java b/java_gen/templates/custom/OFMatchV3Ver12_toString.java
new file mode 100644
index 0000000..3b2783b
--- /dev/null
+++ b/java_gen/templates/custom/OFMatchV3Ver12_toString.java
@@ -0,0 +1 @@
+//:: include("custom/OFMatch_toString.java", msg=msg, has_parent=False)
diff --git a/java_gen/templates/custom/OFMatchV3Ver13.Builder.java b/java_gen/templates/custom/OFMatchV3Ver13.Builder.java
index 79cbdbc..ae2ecaa 100644
--- a/java_gen/templates/custom/OFMatchV3Ver13.Builder.java
+++ b/java_gen/templates/custom/OFMatchV3Ver13.Builder.java
@@ -1,107 +1 @@
-
- private OFOxmList.Builder oxmListBuilder;
-
- private void initBuilder() {
- if (oxmListBuilder != null)
- return;
- oxmListBuilder = new OFOxmList.Builder();
- }
-
- private void updateOxmList() {
- this.oxmList = this.oxmListBuilder.build();
- this.oxmListSet = true;
- }
-
- private <F extends OFValueType<F>> OFOxm<F> getOxm(MatchField<F> field) {
-//:: if has_parent:
- return this.oxmListSet ? this.oxmList.get(field) : parentMessage.oxmList.get(field);
-//:: else:
- return this.oxmListSet ? this.oxmList.get(field) : null;
-//:: #endif
- }
-
- @Override
- public <F extends OFValueType<F>> F get(MatchField<F> field)
- throws UnsupportedOperationException {
- OFOxm<F> value = getOxm(field);
- if (value == null)
- return null;
- return value.getValue();
- }
-
- @Override
- public <F extends OFValueType<F>> Masked<F> getMasked(MatchField<F> field)
- throws UnsupportedOperationException {
- OFOxm<F> value = getOxm(field);
- if (value == null || !value.isMasked())
- return null;
- // TODO: If changing OXMs to extend Masked, then use it here
- return Masked.of(value.getValue(), value.getMask());
- }
-
- @Override
- public boolean supports(MatchField<?> field) {
- return supportsField(field);
- }
-
- @Override
- public boolean supportsMasked(MatchField<?> field) {
- return supportsField(field);
- }
-
- @Override
- public boolean isExact(MatchField<?> field) {
- OFOxm<?> value = getOxm(field);
- return (value != null && !value.isMasked());
- }
-
- @Override
- public boolean isFullyWildcarded(MatchField<?> field) {
- OFOxm<?> value = getOxm(field);
- return (value == null);
- }
-
- @Override
- public boolean isPartiallyMasked(MatchField<?> field) {
- OFOxm<?> value = getOxm(field);
- return (value != null && value.isMasked());
- }
-
- @Override
- public <F extends OFValueType<F>> Match.Builder setExact(
- MatchField<F> field, F value) {
- initBuilder();
- OFOxm<F> oxm = OFFactories.getFactory(OFVersion.OF_13).oxms().fromValue(value, field);
- this.oxmListBuilder.set(oxm);
- updateOxmList();
- return this;
- }
-
- @Override
- public <F extends OFValueType<F>> Match.Builder setMasked(
- MatchField<F> field, F value, F mask) {
- initBuilder();
- OFOxm<F> oxm = OFFactories.getFactory(OFVersion.OF_13).oxms().fromValueAndMask(value, mask, field);
- this.oxmListBuilder.set(oxm);
- updateOxmList();
- return this;
- }
-
- @Override
- public <F extends OFValueType<F>> Match.Builder setMasked(
- MatchField<F> field, Masked<F> valueWithMask) {
- initBuilder();
- OFOxm<F> oxm = OFFactories.getFactory(OFVersion.OF_13).oxms().fromMasked(valueWithMask, field);
- this.oxmListBuilder.set(oxm);
- updateOxmList();
- return this;
- }
-
- @Override
- public <F extends OFValueType<F>> Match.Builder wildcard(MatchField<F> field) {
- initBuilder();
- this.oxmListBuilder.unset(field);
- updateOxmList();
- return this;
- }
-
+//:: include("custom/OFMatchV3.Builder.java", msg=msg, version=version, has_parent=False)
diff --git a/java_gen/templates/custom/OFMatchV3Ver13.java b/java_gen/templates/custom/OFMatchV3Ver13.java
index dc8e637..225b0dc 100644
--- a/java_gen/templates/custom/OFMatchV3Ver13.java
+++ b/java_gen/templates/custom/OFMatchV3Ver13.java
@@ -1,112 +1 @@
-//:: from generic_utils import OrderedSet
-//:: from java_gen.java_model import model
- @Override
- public <F extends OFValueType<F>> F get(MatchField<F> field)
- throws UnsupportedOperationException {
- if (!supports(field))
- throw new UnsupportedOperationException("OFMatchV3Ver13 does not support matching on field " + field.getName());
-
- OFOxm<F> oxm = this.oxmList.get(field);
-
- if (oxm == null || !field.arePrerequisitesOK(this))
- return null;
-
- return oxm.getValue();
- }
-
- @Override
- public <F extends OFValueType<F>> Masked<F> getMasked(MatchField<F> field)
- throws UnsupportedOperationException {
- if (!supportsMasked(field))
- throw new UnsupportedOperationException("OFMatchV3Ver13 does not support masked matching on field " + field.getName());
-
- OFOxm<F> oxm = this.oxmList.get(field);
-
- if (oxm == null || !field.arePrerequisitesOK(this))
- return null;
-
- if (oxm.getMask() == null)
- return null;
-
- // TODO: Make OfOxm extend Masked and just return the OXM?
- return Masked.of(oxm.getValue(), oxm.getMask());
- }
-
- private static boolean supportsField(MatchField<?> field) {
- switch (field.id) {
- //:: for id_constant in sorted(set(id_constant for _, id_constant, _ in model.oxm_map.values())):
- case ${id_constant}:
- //:: #endfor
- return true;
- default:
- return false;
- }
- }
-
- @Override
- public boolean supports(MatchField<?> field) {
- return supportsField(field);
- }
-
- @Override
- public boolean supportsMasked(MatchField<?> field) {
- return supportsField(field);
- }
-
- @Override
- public boolean isExact(MatchField<?> field) {
- if (!supports(field))
- throw new UnsupportedOperationException("OFMatchV3Ver13 does not support matching on field " + field.getName());
-
- OFOxm<?> oxm = this.oxmList.get(field);
-
- return oxm != null && !oxm.isMasked();
- }
-
- @Override
- public boolean isFullyWildcarded(MatchField<?> field) {
- if (!supports(field))
- throw new UnsupportedOperationException("OFMatchV3Ver13 does not support matching on field " + field.getName());
-
- OFOxm<?> oxm = this.oxmList.get(field);
-
- return oxm == null;
- }
-
- @Override
- public boolean isPartiallyMasked(MatchField<?> field) {
- if (!supports(field))
- throw new UnsupportedOperationException("OFMatchV3Ver13 does not support matching on field " + field.getName());
-
- OFOxm<?> oxm = this.oxmList.get(field);
-
- return oxm != null && oxm.isMasked();
- }
-
- private class MatchFieldIterator extends AbstractIterator<MatchField<?>> {
- private Iterator<OFOxm<?>> oxmIterator;
-
- MatchFieldIterator() {
- oxmIterator = oxmList.iterator();
- }
-
- @Override
- protected MatchField<?> computeNext() {
- while(oxmIterator.hasNext()) {
- OFOxm<?> oxm = oxmIterator.next();
- if(oxm.getMatchField().arePrerequisitesOK(OFMatchV3Ver13.this))
- return oxm.getMatchField();
- }
- endOfData();
- return null;
- }
- }
-
- @Override
- public Iterable<MatchField<?>> getMatchFields() {
- return new Iterable<MatchField<?>>() {
- public Iterator<MatchField<?>> iterator() {
- return new MatchFieldIterator();
- }
- };
- }
+//:: include("custom/OFMatchV3.java", msg=msg, has_parent=False)
diff --git a/java_gen/templates/custom/OFMatchV3Ver14.Builder.java b/java_gen/templates/custom/OFMatchV3Ver14.Builder.java
new file mode 100644
index 0000000..ae2ecaa
--- /dev/null
+++ b/java_gen/templates/custom/OFMatchV3Ver14.Builder.java
@@ -0,0 +1 @@
+//:: include("custom/OFMatchV3.Builder.java", msg=msg, version=version, has_parent=False)
diff --git a/java_gen/templates/custom/OFMatchV3Ver14.java b/java_gen/templates/custom/OFMatchV3Ver14.java
new file mode 100644
index 0000000..225b0dc
--- /dev/null
+++ b/java_gen/templates/custom/OFMatchV3Ver14.java
@@ -0,0 +1 @@
+//:: include("custom/OFMatchV3.java", msg=msg, has_parent=False)
diff --git a/java_gen/templates/custom/OFMatchV3Ver14_toString.java b/java_gen/templates/custom/OFMatchV3Ver14_toString.java
new file mode 100644
index 0000000..3b2783b
--- /dev/null
+++ b/java_gen/templates/custom/OFMatchV3Ver14_toString.java
@@ -0,0 +1 @@
+//:: include("custom/OFMatch_toString.java", msg=msg, has_parent=False)
diff --git a/java_gen/templates/of_class.java b/java_gen/templates/of_class.java
index f1d72b2..071f177 100644
--- a/java_gen/templates/of_class.java
+++ b/java_gen/templates/of_class.java
@@ -88,7 +88,7 @@
//:: include("_field_accessors.java", msg=msg, generate_setters=False, builder=False, has_parent=False)
//:: if os.path.exists("%s/custom/%s.java" % (template_dir, msg.name)):
- //:: include("custom/%s.java" % msg.name, msg=msg)
+ //:: include("custom/%s.java" % msg.name, msg=msg, version=version)
//:: #endif
//:: if msg.data_members:
@@ -124,7 +124,7 @@
//
//:: if os.path.exists("%s/custom/%s.Builder_normalize_stanza.java" % (template_dir, msg.name)):
- //:: include("custom/%s.Builder_normalize_stanza.java" % msg.name, msg=msg, has_parent=False)
+ //:: include("custom/%s.Builder_normalize_stanza.java" % msg.name, msg=msg, version=version, has_parent=False)
//:: #endif
return new ${impl_class}(
//:: for i, prop in enumerate(msg.data_members):
@@ -134,7 +134,7 @@
);
}
//:: if os.path.exists("%s/custom/%s.Builder.java" % (template_dir, msg.name)):
- //:: include("custom/%s.Builder.java" % msg.name, msg=msg, has_parent=True)
+ //:: include("custom/%s.Builder.java" % msg.name, msg=msg, version=version, has_parent=True)
//:: #endif
}
@@ -164,7 +164,7 @@
//:: #endfor
//:: if os.path.exists("%s/custom/%s.Builder_normalize_stanza.java" % (template_dir, msg.name)):
- //:: include("custom/%s.Builder_normalize_stanza.java" % msg.name, msg=msg, has_parent=False)
+ //:: include("custom/%s.Builder_normalize_stanza.java" % msg.name, msg=msg, version=version, has_parent=False)
//:: #endif
return new ${impl_class}(
@@ -175,7 +175,7 @@
);
}
//:: if os.path.exists("%s/custom/%s.Builder.java" % (template_dir, msg.name)):
- //:: include("custom/%s.Builder.java" % msg.name, msg=msg, has_parent=False)
+ //:: include("custom/%s.Builder.java" % msg.name, msg=msg, version=version, has_parent=False)
//:: #endif
}
@@ -249,7 +249,7 @@
//:: if msg.data_members:
//:: if os.path.exists("%s/custom/%s.Reader_normalize_stanza.java" % (template_dir, msg.name)):
- //:: include("custom/%s.Reader_normalize_stanza.java" % msg.name, msg=msg, has_parent=False)
+ //:: include("custom/%s.Reader_normalize_stanza.java" % msg.name, msg=msg, version=version, has_parent=False)
//:: #endif
${impl_class} ${msg.variable_name} = new ${impl_class}(
${",\n ".join(
@@ -364,7 +364,7 @@
}
//:: if os.path.exists("%s/custom/%s_toString.java" % (template_dir, msg.name)):
- //:: include("custom/%s_toString.java" % msg.name, msg=msg, has_parent=False)
+ //:: include("custom/%s_toString.java" % msg.name, msg=msg, version=version, has_parent=False)
//:: else:
@Override
public String toString() {
diff --git a/loxi_globals.py b/loxi_globals.py
index e8b21bd..b4662cb 100644
--- a/loxi_globals.py
+++ b/loxi_globals.py
@@ -37,12 +37,14 @@
VERSION_1_1 = OFVersion("1.1", 2)
VERSION_1_2 = OFVersion("1.2", 3)
VERSION_1_3 = OFVersion("1.3", 4)
+ VERSION_1_4 = OFVersion("1.4", 5)
all_supported = (
VERSION_1_0,
VERSION_1_1,
VERSION_1_2,
VERSION_1_3,
+ VERSION_1_4,
)
wire_version_map = { v.wire_version : v for v in all_supported }
diff --git a/loxi_ir/ir_offset.py b/loxi_ir/ir_offset.py
index 9c6a5c1..c65cfed 100644
--- a/loxi_ir/ir_offset.py
+++ b/loxi_ir/ir_offset.py
@@ -35,6 +35,7 @@
2: "uint32_t",
3: "uint32_t",
4: "uint32_t",
+ 5: "uint32_t",
"short_name":"port_no"
},
of_port_desc_t = {
@@ -42,6 +43,7 @@
2: "of_port_desc_t",
3: "of_port_desc_t",
4: "of_port_desc_t",
+ 5: "of_port_desc_t",
"short_name":"port_desc"
},
of_bsn_vport_t = {
@@ -49,6 +51,7 @@
2: "of_bsn_vport_t",
3: "of_bsn_vport_t",
4: "of_bsn_vport_t",
+ 5: "of_bsn_vport_t",
"short_name":"bsn_vport"
},
of_fm_cmd_t = { # Flow mod command went from u16 to u8
@@ -56,6 +59,7 @@
2: "uint8_t",
3: "uint8_t",
4: "uint8_t",
+ 5: "uint8_t",
"short_name":"fm_cmd"
},
of_wc_bmap_t = { # Wildcard bitmap
@@ -63,6 +67,7 @@
2: "uint32_t",
3: "uint64_t",
4: "uint64_t",
+ 5: "uint64_t",
"short_name":"wc_bmap"
},
of_match_bmap_t = { # Match bitmap
@@ -70,6 +75,7 @@
2: "uint32_t",
3: "uint64_t",
4: "uint64_t",
+ 5: "uint64_t",
"short_name":"match_bmap"
},
of_match_t = { # Match object
@@ -77,6 +83,7 @@
2: "of_match_v2_t",
3: "of_match_v3_t",
4: "of_match_v3_t", # Currently uses same match as 1.2 (v3).
+ 5: "of_match_v3_t", # Currently uses same match as 1.2 (v3).
"short_name":"match"
},
)
diff --git a/openflow_input/oxm-1.2 b/openflow_input/oxm-1.2
index 5006cff..dd596bd 100644
--- a/openflow_input/oxm-1.2
+++ b/openflow_input/oxm-1.2
@@ -31,6 +31,7 @@
#version 3
#version 4
+#version 5
struct of_oxm {
uint32_t type_len == ?;
diff --git a/openflow_input/oxm-1.3 b/openflow_input/oxm-1.3
index 8574236..ac57589 100644
--- a/openflow_input/oxm-1.3
+++ b/openflow_input/oxm-1.3
@@ -29,6 +29,7 @@
// governing permissions and limitations under the EPL.
#version 4
+#version 5
struct of_oxm_tunnel_id : of_oxm {
uint32_t type_len == 0x80004c08;
diff --git a/openflow_input/standard-1.3 b/openflow_input/standard-1.3
index 64a465d..3a627e1 100644
--- a/openflow_input/standard-1.3
+++ b/openflow_input/standard-1.3
@@ -1700,7 +1700,7 @@
struct of_table_feature_prop_experimenter : of_table_feature_prop {
uint16_t type == 65534;
uint16_t length;
- uint32_t experimenter;
+ uint32_t experimenter == ?;
uint32_t subtype;
of_octets_t experimenter_data;
};
@@ -1708,7 +1708,7 @@
struct of_table_feature_prop_experimenter_miss : of_table_feature_prop {
uint16_t type == 65535;
uint16_t length;
- uint32_t experimenter;
+ uint32_t experimenter == ?;
uint32_t subtype;
of_octets_t experimenter_data;
};
diff --git a/openflow_input/standard-1.4 b/openflow_input/standard-1.4
new file mode 100644
index 0000000..2f495ed
--- /dev/null
+++ b/openflow_input/standard-1.4
@@ -0,0 +1,2256 @@
+// Copyright 2013, Big Switch Networks, Inc.
+//
+// LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
+// the following special exception:
+//
+// LOXI Exception
+//
+// As a special exception to the terms of the EPL, you may distribute libraries
+// generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
+// that copyright and licensing notices generated by LoxiGen are not altered or removed
+// from the LoxiGen Libraries and the notice provided below is (i) included in
+// the LoxiGen Libraries, if distributed in source code form and (ii) included in any
+// documentation for the LoxiGen Libraries, if distributed in binary form.
+//
+// Notice: "Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
+//
+// You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
+// a copy of the EPL at:
+//
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// EPL for the specific language governing permissions and limitations
+// under the EPL.
+//
+// Also derived from the OpenFlow header files which have these copyrights:
+// Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+// Copyright (c) 2011, 2012 Open Networking Foundation
+
+#version 5
+
+enum macro_definitions {
+ OFP_MAX_TABLE_NAME_LEN = 32,
+ OFP_MAX_PORT_NAME_LEN = 16,
+
+ OFP_TCP_PORT = 6653,
+ OFP_SSL_PORT = 6653,
+
+ OFP_ETH_ALEN = 6,
+
+ OFP_DEFAULT_MISS_SEND_LEN = 128,
+
+ OFP_VLAN_NONE = 0,
+
+ OFP_FLOW_PERMANENT = 0,
+
+ OFP_DEFAULT_PRIORITY = 0x8000,
+
+ OFP_NO_BUFFER = 0xffffffff,
+
+ DESC_STR_LEN = 256,
+ SERIAL_NUM_LEN = 32,
+
+ OFPQ_ALL = 0xffffffff,
+ OFPQ_MAX_RATE_UNCFG = 0xffff,
+ OFPQ_MIN_RATE_UNCFG = 0xffff,
+};
+
+enum ofp_port(wire_type=uint32_t) {
+ OFPP_MAX = 0xffffff00,
+ OFPP_IN_PORT = 0xfffffff8,
+ OFPP_TABLE = 0xfffffff9,
+ OFPP_NORMAL = 0xfffffffa,
+ OFPP_FLOOD = 0xfffffffb,
+ OFPP_ALL = 0xfffffffc,
+ OFPP_CONTROLLER = 0xfffffffd,
+ OFPP_LOCAL = 0xfffffffe,
+ OFPP_ANY = 0xffffffff,
+};
+
+enum ofp_type(wire_type=uint8_t) {
+ OFPT_HELLO = 0,
+ OFPT_ERROR = 1,
+ OFPT_ECHO_REQUEST = 2,
+ OFPT_ECHO_REPLY = 3,
+ OFPT_EXPERIMENTER = 4,
+ OFPT_FEATURES_REQUEST = 5,
+ OFPT_FEATURES_REPLY = 6,
+ OFPT_GET_CONFIG_REQUEST = 7,
+ OFPT_GET_CONFIG_REPLY = 8,
+ OFPT_SET_CONFIG = 9,
+ OFPT_PACKET_IN = 10,
+ OFPT_FLOW_REMOVED = 11,
+ OFPT_PORT_STATUS = 12,
+ OFPT_PACKET_OUT = 13,
+ OFPT_FLOW_MOD = 14,
+ OFPT_GROUP_MOD = 15,
+ OFPT_PORT_MOD = 16,
+ OFPT_TABLE_MOD = 17,
+ OFPT_STATS_REQUEST = 18,
+ OFPT_STATS_REPLY = 19,
+ OFPT_BARRIER_REQUEST = 20,
+ OFPT_BARRIER_REPLY = 21,
+ OFPT_ROLE_REQUEST = 24,
+ OFPT_ROLE_REPLY = 25,
+ OFPT_GET_ASYNC_REQUEST = 26,
+ OFPT_GET_ASYNC_REPLY = 27,
+ OFPT_SET_ASYNC = 28,
+ OFPT_METER_MOD = 29,
+ OFPT_ROLE_STATUS = 30,
+ OFPT_TABLE_STATUS = 31,
+ OFPT_REQUESTFORWARD = 32,
+ OFPT_BUNDLE_CONTROL = 33,
+ OFPT_BUNDLE_ADD_MESSAGE = 34,
+};
+
+enum ofp_config_flags(wire_type=uint16_t, bitmask=True) {
+ OFPC_FRAG_NORMAL = 0,
+ OFPC_FRAG_DROP = 1,
+ OFPC_FRAG_REASM = 2,
+ OFPC_FRAG_MASK = 3,
+};
+
+enum ofp_table_config(wire_type=uint32_t, bitmask=True) {
+ OFPTC_DEPRECATED_MASK = 0x3,
+ OFPTC_EVICTION = 0x4,
+ OFPTC_VACANCY_EVENTS = 0x8,
+};
+
+enum ofp_table(wire_type=uint8_t, complete=False) {
+ OFPTT_MAX = 0xfe,
+ OFPTT_ALL = 0xff,
+};
+
+enum ofp_capabilities(wire_type=uint32_t, bitmask=True) {
+ OFPC_FLOW_STATS = 0x1,
+ OFPC_TABLE_STATS = 0x2,
+ OFPC_PORT_STATS = 0x4,
+ OFPC_GROUP_STATS = 0x8,
+ OFPC_IP_REASM = 0x20,
+ OFPC_QUEUE_STATS = 0x40,
+ OFPC_PORT_BLOCKED = 0x100,
+};
+
+enum ofp_port_config(wire_type=uint32_t, bitmask=True) {
+ OFPPC_PORT_DOWN = 0x1,
+ OFPPC_NO_RECV = 0x4,
+ OFPPC_NO_FWD = 0x20,
+ OFPPC_NO_PACKET_IN = 0x40,
+ OFPPC_BSN_MIRROR_DEST = 0x80000000,
+};
+
+enum ofp_port_state(wire_type=uint32_t, bitmask=True) {
+ OFPPS_LINK_DOWN = 0x1,
+ OFPPS_BLOCKED = 0x2,
+ OFPPS_LIVE = 0x4,
+};
+
+enum ofp_port_features(wire_type=uint32_t, bitmask=True) {
+ OFPPF_10MB_HD = 0x1,
+ OFPPF_10MB_FD = 0x2,
+ OFPPF_100MB_HD = 0x4,
+ OFPPF_100MB_FD = 0x8,
+ OFPPF_1GB_HD = 0x10,
+ OFPPF_1GB_FD = 0x20,
+ OFPPF_10GB_FD = 0x40,
+ OFPPF_40GB_FD = 0x80,
+ OFPPF_100GB_FD = 0x100,
+ OFPPF_1TB_FD = 0x200,
+ OFPPF_OTHER = 0x400,
+ OFPPF_COPPER = 0x800,
+ OFPPF_FIBER = 0x1000,
+ OFPPF_AUTONEG = 0x2000,
+ OFPPF_PAUSE = 0x4000,
+ OFPPF_PAUSE_ASYM = 0x8000,
+};
+
+enum ofp_port_reason(wire_type=uint8_t) {
+ OFPPR_ADD = 0,
+ OFPPR_DELETE = 1,
+ OFPPR_MODIFY = 2,
+};
+
+enum ofp_match_type(wire_type=uint16_t) {
+ OFPMT_STANDARD = 0,
+ OFPMT_OXM = 1,
+};
+
+enum ofp_oxm_class(wire_type=uint16_t) {
+ OFPXMC_NXM_0 = 0,
+ OFPXMC_NXM_1 = 1,
+ OFPXMC_OPENFLOW_BASIC = 0x8000,
+ OFPXMC_EXPERIMENTER = 0xffff,
+};
+
+enum ofp_vlan_id(wire_type=uint16_t) {
+ OFPVID_NONE = 0,
+ OFPVID_PRESENT = 0x1000,
+};
+
+// FIXME: OF spec specified this as '9' bits, implicitly adding
+// to full byte
+enum ofp_ipv6exthdr_flags(wire_type=uint16_t, bitmask=True) {
+ OFPIEH_NONEXT = 0x1,
+ OFPIEH_ESP = 0x2,
+ OFPIEH_AUTH = 0x4,
+ OFPIEH_DEST = 0x8,
+ OFPIEH_FRAG = 0x10,
+ OFPIEH_ROUTER = 0x20,
+ OFPIEH_HOP = 0x40,
+ OFPIEH_UNREP = 0x80,
+ OFPIEH_UNSEQ = 0x100,
+};
+
+enum ofp_action_type(wire_type=uint16_t) {
+ OFPAT_OUTPUT = 0,
+ OFPAT_COPY_TTL_OUT = 0xb,
+ OFPAT_COPY_TTL_IN = 0xc,
+ OFPAT_SET_MPLS_TTL = 0xf,
+ OFPAT_DEC_MPLS_TTL = 0x10,
+ OFPAT_PUSH_VLAN = 0x11,
+ OFPAT_POP_VLAN = 0x12,
+ OFPAT_PUSH_MPLS = 0x13,
+ OFPAT_POP_MPLS = 0x14,
+ OFPAT_SET_QUEUE = 0x15,
+ OFPAT_GROUP = 0x16,
+ OFPAT_SET_NW_TTL = 0x17,
+ OFPAT_DEC_NW_TTL = 0x18,
+ OFPAT_SET_FIELD = 0x19,
+ OFPAT_PUSH_PBB = 0x1a,
+ OFPAT_POP_PBB = 0x1b,
+ OFPAT_EXPERIMENTER = 0xffff,
+};
+
+enum ofp_controller_max_len(wire_type=uint16_t, complete=False) {
+ OFPCML_MAX = 0xffe5,
+ OFPCML_NO_BUFFER = 0xffff,
+};
+
+enum ofp_instruction_type(wire_type=uint16_t, bitmask=True) {
+ OFPIT_GOTO_TABLE = 0x1,
+ OFPIT_WRITE_METADATA = 0x2,
+ OFPIT_WRITE_ACTIONS = 0x3,
+ OFPIT_APPLY_ACTIONS = 0x4,
+ OFPIT_CLEAR_ACTIONS = 0x5,
+ OFPIT_METER = 0x6,
+ OFPIT_EXPERIMENTER = 0xffff,
+};
+
+enum ofp_flow_mod_command(wire_type=uint8_t) {
+ OFPFC_ADD = 0,
+ OFPFC_MODIFY = 1,
+ OFPFC_MODIFY_STRICT = 2,
+ OFPFC_DELETE = 3,
+ OFPFC_DELETE_STRICT = 4,
+};
+
+enum ofp_flow_mod_flags(wire_type=uint16_t, bitmask=True) {
+ OFPFF_SEND_FLOW_REM = 0x1,
+ OFPFF_CHECK_OVERLAP = 0x2,
+ OFPFF_RESET_COUNTS = 0x4,
+ OFPFF_NO_PKT_COUNTS = 0x8,
+ OFPFF_NO_BYT_COUNTS = 0x10,
+
+ /* Non-standard, enabled by an experimenter message */
+ /* See the bsn_flow_idle input file */
+ OFPFF_BSN_SEND_IDLE = 0x80,
+};
+
+enum ofp_group(wire_type=uint32_t, complete=False) {
+ OFPG_MAX = 0xffffff00,
+ OFPG_ALL = 0xfffffffc,
+ OFPG_ANY = 0xffffffff,
+};
+
+enum ofp_group_mod_command(wire_type=uint16_t) {
+ OFPGC_ADD = 0,
+ OFPGC_MODIFY = 1,
+ OFPGC_DELETE = 2,
+};
+
+enum ofp_group_type(wire_type=uint8_t) {
+ OFPGT_ALL = 0,
+ OFPGT_SELECT = 1,
+ OFPGT_INDIRECT = 2,
+ OFPGT_FF = 3,
+};
+
+enum ofp_packet_in_reason(wire_type=uint8_t) {
+ OFPR_NO_MATCH = 0,
+ OFPR_ACTION = 1,
+ OFPR_INVALID_TTL = 2,
+ OFPR_ACTION_SET = 3,
+ OFPR_GROUP = 4,
+ OFPR_PACKET_OUT = 5,
+
+ // non-standard BSN extensions. OF does not have a standard-conformant
+ // way to extend the set of packet_in reasons
+ OFPR_BSN_NEW_HOST = 128,
+ OFPR_BSN_STATION_MOVE = 129,
+ OFPR_BSN_BAD_VLAN = 130,
+ OFPR_BSN_DESTINATION_LOOKUP_FAILURE = 131,
+ OFPR_BSN_NO_ROUTE = 132,
+ OFPR_BSN_ICMP_ECHO_REQUEST = 133,
+ OFPR_BSN_DEST_NETWORK_UNREACHABLE = 134,
+ OFPR_BSN_DEST_HOST_UNREACHABLE = 135,
+ OFPR_BSN_DEST_PORT_UNREACHABLE = 136,
+ OFPR_BSN_FRAGMENTATION_REQUIRED = 137,
+ OFPR_BSN_ARP = 139,
+ OFPR_BSN_DHCP = 140,
+ OFPR_BSN_DEBUG = 141,
+ OFPR_BSN_PACKET_OF_DEATH = 142,
+};
+
+enum ofp_flow_removed_reason(wire_type=uint8_t) {
+ OFPRR_IDLE_TIMEOUT = 0,
+ OFPRR_HARD_TIMEOUT = 1,
+ OFPRR_DELETE = 2,
+ OFPRR_GROUP_DELETE = 3,
+ OFPRR_METER_DELETE = 4,
+ OFPRR_EVICTION = 5,
+};
+
+enum ofp_meter(wire_type=uint32_t, complete=False) {
+ OFPM_MAX = 0xffff0000,
+ OFPM_SLOWPATH = 0xfffffffd,
+ OFPM_CONTROLLER = 0xfffffffe,
+ OFPM_ALL = 0xffffffff,
+};
+
+enum ofp_meter_band_type(wire_type=uint16_t) {
+ OFPMBT_DROP = 0x1,
+ OFPMBT_DSCP_REMARK = 0x2,
+ OFPMBT_EXPERIMENTER = 0xffff,
+};
+
+enum ofp_meter_mod_command(wire_type=uint16_t) {
+ OFPMC_ADD = 0,
+ OFPMC_MODIFY = 1,
+ OFPMC_DELETE = 2,
+};
+
+enum ofp_meter_flags(wire_type=uint16_t, bitmask=True) {
+ OFPMF_KBPS = 0x1,
+ OFPMF_PKTPS = 0x2,
+ OFPMF_BURST = 0x4,
+ OFPMF_STATS = 0x8,
+};
+
+enum ofp_error_type(wire_type=uint16_t) {
+ OFPET_HELLO_FAILED = 0,
+ OFPET_BAD_REQUEST = 1,
+ OFPET_BAD_ACTION = 2,
+ OFPET_BAD_INSTRUCTION = 3,
+ OFPET_BAD_MATCH = 4,
+ OFPET_FLOW_MOD_FAILED = 5,
+ OFPET_GROUP_MOD_FAILED = 6,
+ OFPET_PORT_MOD_FAILED = 7,
+ OFPET_TABLE_MOD_FAILED = 8,
+ OFPET_QUEUE_OP_FAILED = 9,
+ OFPET_SWITCH_CONFIG_FAILED = 10,
+ OFPET_ROLE_REQUEST_FAILED = 11,
+ OFPET_METER_MOD_FAILED = 12,
+ OFPET_TABLE_FEATURES_FAILED = 13,
+ OFPET_BAD_PROPERTY = 14,
+ OFPET_ASYNC_CONFIG_FAILED = 15,
+ OFPET_FLOW_MONITOR_FAILED = 16,
+ OFPET_BUNDLE_FAILED = 17,
+ OFPET_EXPERIMENTER = 0xffff,
+};
+
+enum ofp_hello_failed_code(wire_type=uint16_t) {
+ OFPHFC_INCOMPATIBLE = 0,
+ OFPHFC_EPERM = 1,
+};
+
+enum ofp_bad_request_code(wire_type=uint16_t) {
+ OFPBRC_BAD_VERSION = 0,
+ OFPBRC_BAD_TYPE = 1,
+ OFPBRC_BAD_STAT = 2,
+ OFPBRC_BAD_EXPERIMENTER = 3,
+ OFPBRC_BAD_EXPERIMENTER_TYPE = 4,
+ OFPBRC_EPERM = 5,
+ OFPBRC_BAD_LEN = 6,
+ OFPBRC_BUFFER_EMPTY = 7,
+ OFPBRC_BUFFER_UNKNOWN = 8,
+ OFPBRC_BAD_TABLE_ID = 9,
+ OFPBRC_IS_SLAVE = 10,
+ OFPBRC_BAD_PORT = 11,
+ OFPBRC_BAD_PACKET = 12,
+ OFPBRC_MULTIPART_BUFFER_OVERFLOW = 13,
+ OFPBRC_MULTIPART_REQUEST_TIMEOUT = 14,
+ OFPBRC_MULTIPART_REPLY_TIMEOUT = 15,
+};
+
+enum ofp_bad_action_code(wire_type=uint16_t) {
+ OFPBAC_BAD_TYPE = 0,
+ OFPBAC_BAD_LEN = 1,
+ OFPBAC_BAD_EXPERIMENTER = 2,
+ OFPBAC_BAD_EXPERIMENTER_TYPE = 3,
+ OFPBAC_BAD_OUT_PORT = 4,
+ OFPBAC_BAD_ARGUMENT = 5,
+ OFPBAC_EPERM = 6,
+ OFPBAC_TOO_MANY = 7,
+ OFPBAC_BAD_QUEUE = 8,
+ OFPBAC_BAD_OUT_GROUP = 9,
+ OFPBAC_MATCH_INCONSISTENT = 10,
+ OFPBAC_UNSUPPORTED_ORDER = 11,
+ OFPBAC_BAD_TAG = 12,
+ OFPBAC_BAD_SET_TYPE = 13,
+ OFPBAC_BAD_SET_LEN = 14,
+ OFPBAC_BAD_SET_ARGUMENT = 15,
+};
+
+enum ofp_bad_instruction_code(wire_type=uint16_t) {
+ OFPBIC_UNKNOWN_INST = 0,
+ OFPBIC_UNSUP_INST = 1,
+ OFPBIC_BAD_TABLE_ID = 2,
+ OFPBIC_UNSUP_METADATA = 3,
+ OFPBIC_UNSUP_METADATA_MASK = 4,
+ OFPBIC_BAD_EXPERIMENTER = 5,
+ OFPBIC_BAD_EXPERIMENTER_TYPE = 6,
+ OFPBIC_BAD_LEN = 7,
+ OFPBIC_EPERM = 8,
+ OFPBIC_DUP_INST = 9,
+};
+
+enum ofp_bad_match_code(wire_type=uint16_t) {
+ OFPBMC_BAD_TYPE = 0,
+ OFPBMC_BAD_LEN = 1,
+ OFPBMC_BAD_TAG = 2,
+ OFPBMC_BAD_DL_ADDR_MASK = 3,
+ OFPBMC_BAD_NW_ADDR_MASK = 4,
+ OFPBMC_BAD_WILDCARDS = 5,
+ OFPBMC_BAD_FIELD = 6,
+ OFPBMC_BAD_VALUE = 7,
+ OFPBMC_BAD_MASK = 8,
+ OFPBMC_BAD_PREREQ = 9,
+ OFPBMC_DUP_FIELD = 10,
+ OFPBMC_EPERM = 11,
+};
+
+enum ofp_flow_mod_failed_code(wire_type=uint16_t) {
+ OFPFMFC_UNKNOWN = 0,
+ OFPFMFC_TABLE_FULL = 1,
+ OFPFMFC_BAD_TABLE_ID = 2,
+ OFPFMFC_OVERLAP = 3,
+ OFPFMFC_EPERM = 4,
+ OFPFMFC_BAD_TIMEOUT = 5,
+ OFPFMFC_BAD_COMMAND = 6,
+ OFPFMFC_BAD_FLAGS = 7,
+ OFPFMFC_CANT_SYNC = 8,
+ OFPFMFC_BAD_PRIORITY = 9,
+};
+
+enum ofp_group_mod_failed_code(wire_type=uint16_t) {
+ OFPGMFC_GROUP_EXISTS = 0,
+ OFPGMFC_INVALID_GROUP = 1,
+ OFPGMFC_WEIGHT_UNSUPPORTED = 2,
+ OFPGMFC_OUT_OF_GROUPS = 3,
+ OFPGMFC_OUT_OF_BUCKETS = 4,
+ OFPGMFC_CHAINING_UNSUPPORTED = 5,
+ OFPGMFC_WATCH_UNSUPPORTED = 6,
+ OFPGMFC_LOOP = 7,
+ OFPGMFC_UNKNOWN_GROUP = 8,
+ OFPGMFC_CHAINED_GROUP = 9,
+ OFPGMFC_BAD_TYPE = 10,
+ OFPGMFC_BAD_COMMAND = 11,
+ OFPGMFC_BAD_BUCKET = 12,
+ OFPGMFC_BAD_WATCH = 13,
+ OFPGMFC_EPERM = 14,
+};
+
+enum ofp_port_mod_failed_code(wire_type=uint16_t) {
+ OFPPMFC_BAD_PORT = 0,
+ OFPPMFC_BAD_HW_ADDR = 1,
+ OFPPMFC_BAD_CONFIG = 2,
+ OFPPMFC_BAD_ADVERTISE = 3,
+ OFPPMFC_EPERM = 4,
+};
+
+enum ofp_table_mod_failed_code(wire_type=uint16_t) {
+ OFPTMFC_BAD_TABLE = 0,
+ OFPTMFC_BAD_CONFIG = 1,
+ OFPTMFC_EPERM = 2,
+};
+
+enum ofp_queue_op_failed_code(wire_type=uint16_t) {
+ OFPQOFC_BAD_PORT = 0,
+ OFPQOFC_BAD_QUEUE = 1,
+ OFPQOFC_EPERM = 2,
+};
+
+enum ofp_switch_config_failed_code(wire_type=uint16_t) {
+ OFPSCFC_BAD_FLAGS = 0,
+ OFPSCFC_BAD_LEN = 1,
+ OFPSCFC_EPERM = 2,
+};
+
+enum ofp_role_request_failed_code(wire_type=uint16_t){
+ OFPRRFC_STALE = 0,
+ OFPRRFC_UNSUP = 1,
+ OFPRRFC_BAD_ROLE = 2,
+};
+
+enum ofp_meter_mod_failed_code(wire_type=uint16_t) {
+ OFPMMFC_UNKNOWN = 0,
+ OFPMMFC_METER_EXISTS = 1,
+ OFPMMFC_INVALID_METER = 2,
+ OFPMMFC_UNKNOWN_METER = 3,
+ OFPMMFC_BAD_COMMAND = 4,
+ OFPMMFC_BAD_FLAGS = 5,
+ OFPMMFC_BAD_RATE = 6,
+ OFPMMFC_BAD_BURST = 7,
+ OFPMMFC_BAD_BAND = 8,
+ OFPMMFC_BAD_BAND_VALUE = 9,
+ OFPMMFC_OUT_OF_METERS = 10,
+ OFPMMFC_OUT_OF_BANDS = 11,
+};
+
+enum ofp_table_features_failed_code(wire_type=uint16_t) {
+ OFPTFFC_BAD_TABLE = 0,
+ OFPTFFC_BAD_METADATA = 1,
+ OFPTFFC_EPERM = 5,
+};
+
+enum ofp_bad_property_code(wire_type=uint16_t) {
+ OFPBPC_BAD_TYPE = 0, /* Unknown property type. */
+ OFPBPC_BAD_LEN = 1, /* Length problem in property. */
+ OFPBPC_BAD_VALUE = 2, /* Unsupported property value. */
+ OFPBPC_TOO_MANY = 3, /* Can’t handle this many properties. */
+ OFPBPC_DUP_TYPE = 4, /* A property type was duplicated. */
+ OFPBPC_BAD_EXPERIMENTER = 5, /* Unknown experimenter id specified. */
+ OFPBPC_BAD_EXP_TYPE = 6, /* Unknown exp_type for experimenter id. */
+ OFPBPC_BAD_EXP_VALUE = 7, /* Unknown value for experimenter id. */
+ OFPBPC_EPERM = 8, /* Permissions error. */
+};
+
+
+enum ofp_async_config_failed_code(wire_type=uint16_t) {
+ OFPACFC_INVALID = 0, /* One mask is invalid. */
+ OFPACFC_UNSUPPORTED = 1, /* Requested configuration not supported. */
+ OFPACFC_EPERM = 2, /* Permissions error. */
+};
+
+enum ofp_flow_monitor_failed_code(wire_type=uint16_t) {
+ OFPMOFC_UNKNOWN = 0, /* Unspecified error. */
+ OFPMOFC_MONITOR_EXISTS = 1, /* Monitor not added because a Monitor ADD
+ * attempted to replace an existing Monitor. */
+ OFPMOFC_INVALID_MONITOR = 2, /* Monitor not added because Monitor specified
+ * is invalid. */
+ OFPMOFC_UNKNOWN_MONITOR = 3, /* Monitor not modified because a Monitor
+ MODIFY attempted to modify a non-existent
+ Monitor. */
+ OFPMOFC_BAD_COMMAND = 4, /* Unsupported or unknown command. */
+ OFPMOFC_BAD_FLAGS = 5, /* Flag configuration unsupported. */
+ OFPMOFC_BAD_TABLE_ID = 6, /* Specified table does not exist. */
+ OFPMOFC_BAD_OUT = 7, /* Error in output port/group. */
+};
+
+enum ofp_bundle_failed_code(wire_type=uint16_t) {
+ OFPBFC_UNKNOWN = 0, /* Unspecified error. */
+ OFPBFC_EPERM = 1, /* Permissions error. */
+ OFPBFC_BAD_ID = 2, /* Bundle ID doesn’t exist. */
+ OFPBFC_BUNDLE_EXIST = 3, /* Bundle ID already exist. */
+ OFPBFC_BUNDLE_CLOSED = 4, /* Bundle ID is closed. */
+ OFPBFC_OUT_OF_BUNDLES = 5, /* Too many bundles IDs. */
+ OFPBFC_BAD_TYPE = 6, /* Unsupported or unknown message control type. */
+ OFPBFC_BAD_FLAGS = 7, /* Unsupported, unknown, or inconsistent flags. */
+ OFPBFC_MSG_BAD_LEN = 8, /* Length problem in included message. */
+ OFPBFC_MSG_BAD_XID = 9, /* Inconsistent or duplicate XID. */
+ OFPBFC_MSG_UNSUP = 10, /* Unsupported message in this bundle. */
+ OFPBFC_MSG_CONFLICT = 11, /* Unsupported message combination in this bundle. */
+ OFPBFC_MSG_TOO_MANY = 12, /* Cant handle this many messages in bundle. */
+ OFPBFC_MSG_FAILED = 13, /* One message in bundle failed. */
+ OFPBFC_TIMEOUT = 14, /* Bundle is taking too long. */
+ OFPBFC_BUNDLE_IN_PROGRESS = 15, /* Bundle is locking the resource. */
+};
+
+/* Port stats property types.
+ */
+enum ofp_port_stats_prop_type(wire_type=uint16_t) {
+ OFPPSPT_ETHERNET = 0, /* Ethernet property. */
+ OFPPSPT_OPTICAL = 1, /* Optical property. */
+ OFPPSPT_EXPERIMENTER = 0xFFFF, /* Experimenter property. */
+};
+
+
+enum ofp_stats_type(wire_type=uint16_t) {
+ OFPST_DESC = 0,
+ OFPST_FLOW = 1,
+ OFPST_AGGREGATE = 2,
+ OFPST_TABLE = 3,
+ OFPST_PORT = 4,
+ OFPST_QUEUE = 5,
+ OFPST_GROUP = 6,
+ OFPST_GROUP_DESC = 7,
+ OFPST_GROUP_FEATURES = 8,
+ OFPST_METER = 9,
+ OFPST_METER_CONFIG = 10,
+ OFPST_METER_FEATURES = 11,
+ OFPST_TABLE_FEATURES = 12,
+ OFPST_PORT_DESC = 13,
+ OFPMP_TABLE_DESC = 14,
+ OFPMP_QUEUE_DESC = 15,
+ OFPMP_FLOW_MONITOR = 16,
+ OFPST_EXPERIMENTER = 0xffff,
+};
+
+enum ofp_stats_request_flags(wire_type=uint16_t, bitmask=True) {
+ OFPSF_REQ_MORE = 0x1,
+};
+
+enum ofp_stats_reply_flags(wire_type=uint16_t, bitmask=True) {
+ OFPSF_REPLY_MORE = 0x1,
+};
+
+enum ofp_table_feature_prop_type(wire_type=uint16_t) {
+ OFPTFPT_INSTRUCTIONS = 0,
+ OFPTFPT_INSTRUCTIONS_MISS = 1,
+ OFPTFPT_NEXT_TABLES = 2,
+ OFPTFPT_NEXT_TABLES_MISS = 3,
+ OFPTFPT_WRITE_ACTIONS = 4,
+ OFPTFPT_WRITE_ACTIONS_MISS = 5,
+ OFPTFPT_APPLY_ACTIONS = 6,
+ OFPTFPT_APPLY_ACTIONS_MISS = 7,
+ OFPTFPT_MATCH = 8,
+ OFPTFPT_WILDCARDS = 0xa,
+ OFPTFPT_WRITE_SETFIELD = 0xc,
+ OFPTFPT_WRITE_SETFIELD_MISS = 0xd,
+ OFPTFPT_APPLY_SETFIELD = 0xe,
+ OFPTFPT_APPLY_SETFIELD_MISS = 0xf,
+ OFPTFPT_TABLE_SYNC_FROM = 0x10,
+ OFPTFPT_EXPERIMENTER = 0xfffe,
+ OFPTFPT_EXPERIMENTER_MISS = 0xffff,
+};
+
+enum ofp_group_capabilities(wire_type=uint32_t, bitmask=True) {
+ OFPGFC_SELECT_WEIGHT = 0x1,
+ OFPGFC_SELECT_LIVENESS = 0x2,
+ OFPGFC_CHAINING = 0x4,
+ OFPGFC_CHAINING_CHECKS = 0x8,
+};
+
+enum ofp_controller_role(wire_type=uint32_t) {
+ OFPCR_ROLE_NOCHANGE = 0,
+ OFPCR_ROLE_EQUAL = 1,
+ OFPCR_ROLE_MASTER = 2,
+ OFPCR_ROLE_SLAVE = 3,
+};
+
+enum ofp_hello_elem_type(wire_type=uint16_t) {
+ OFPHET_VERSIONBITMAP = 1,
+};
+
+/* XXX rename to of_message */
+struct of_header {
+ uint8_t version;
+ uint8_t type == ?;
+ uint16_t length;
+ uint32_t xid;
+};
+
+struct of_uint64 {
+ uint64_t value;
+};
+
+// Special structures used for managing scalar list elements
+struct of_uint32 {
+ uint32_t value;
+};
+
+// Special structures used for managing scalar list elements
+struct of_uint8 {
+ uint8_t value;
+};
+
+struct of_hello_elem {
+ uint16_t type == ?;
+ uint16_t length;
+};
+
+struct of_hello_elem_versionbitmap : of_hello_elem {
+ uint16_t type == 1;
+ uint16_t length;
+ list(of_uint32_t) bitmaps;
+};
+
+struct of_hello : of_header {
+ uint8_t version;
+ uint8_t type == 0;
+ uint16_t length;
+ uint32_t xid;
+ list(of_hello_elem_t) elements;
+};
+
+struct of_echo_request : of_header {
+ uint8_t version;
+ uint8_t type == 2;
+ uint16_t length;
+ uint32_t xid;
+ of_octets_t data;
+};
+
+struct of_echo_reply : of_header {
+ uint8_t version;
+ uint8_t type == 3;
+ uint16_t length;
+ uint32_t xid;
+ of_octets_t data;
+};
+
+struct of_experimenter : of_header {
+ uint8_t version;
+ uint8_t type == 4;
+ uint16_t length;
+ uint32_t xid;
+ uint32_t experimenter == ?;
+ uint32_t subtype;
+ of_octets_t data;
+};
+
+struct of_barrier_request : of_header {
+ uint8_t version;
+ uint8_t type == 20;
+ uint16_t length;
+ uint32_t xid;
+};
+
+struct of_barrier_reply : of_header {
+ uint8_t version;
+ uint8_t type == 21;
+ uint16_t length;
+ uint32_t xid;
+};
+
+struct of_get_config_request : of_header {
+ uint8_t version;
+ uint8_t type == 7;
+ uint16_t length;
+ uint32_t xid;
+};
+
+struct of_get_config_reply : of_header {
+ uint8_t version;
+ uint8_t type == 8;
+ uint16_t length;
+ uint32_t xid;
+ enum ofp_config_flags flags;
+ uint16_t miss_send_len;
+};
+
+struct of_set_config : of_header {
+ uint8_t version;
+ uint8_t type == 9;
+ uint16_t length;
+ uint32_t xid;
+ enum ofp_config_flags flags;
+ uint16_t miss_send_len;
+};
+
+struct of_table_mod_prop {
+ uint16_t type == ?; /* One of OFPTMPT_*. */
+ uint16_t length; /* Length in bytes of this property. */
+};
+
+struct of_table_mod : of_header {
+ uint8_t version;
+ uint8_t type == 17;
+ uint16_t length;
+ uint32_t xid;
+ uint8_t table_id;
+ pad(3);
+ uint32_t config;
+ list(of_table_mod_prop_t) properties;
+};
+
+struct of_port_desc_prop {
+ uint16_t type == ?; /* One of OFPPDPT_*. */
+ uint16_t length; /* Length in bytes of this property. */
+};
+
+struct of_port_desc_prop_ethernet : of_port_desc_prop {
+ uint16_t type == 0;
+ uint16_t length;
+ pad(4);
+ uint32_t curr;
+ uint32_t advertised;
+ uint32_t supported;
+ uint32_t peer;
+ uint32_t curr_speed;
+ uint32_t max_speed;
+};
+
+struct of_port_desc {
+ of_port_no_t port_no;
+ uint16_t length;
+ pad(2);
+ of_mac_addr_t hw_addr;
+ pad(2);
+ of_port_name_t name;
+ enum ofp_port_config config; /* Bitmap of OFPPC_* flags. */
+ enum ofp_port_state state; /* Bitmap of OFPPS_* flags. */
+ list(of_port_desc_prop_t) properties;
+};
+
+struct of_features_request : of_header {
+ uint8_t version;
+ uint8_t type == 5;
+ uint16_t length;
+ uint32_t xid;
+};
+
+struct of_features_reply : of_header {
+ uint8_t version;
+ uint8_t type == 6;
+ uint16_t length;
+ uint32_t xid;
+ uint64_t datapath_id;
+ uint32_t n_buffers;
+ uint8_t n_tables;
+ uint8_t auxiliary_id;
+ pad(2);
+ enum ofp_capabilities capabilities;
+ uint32_t reserved;
+};
+
+struct of_port_status : of_header {
+ uint8_t version;
+ uint8_t type == 12;
+ uint16_t length;
+ uint32_t xid;
+ enum ofp_port_reason reason;
+ pad(7);
+ of_port_desc_t desc;
+};
+
+struct of_port_mod_prop {
+ uint16_t type == ?; /* One of OFPPMPT_*. */
+ uint16_t length; /* Length in bytes of this property. */
+};
+
+struct of_port_mod : of_header {
+ uint8_t version;
+ uint8_t type == 16;
+ uint16_t length;
+ uint32_t xid;
+ of_port_no_t port_no;
+ pad(4);
+ of_mac_addr_t hw_addr;
+ pad(2);
+ uint32_t config;
+ uint32_t mask;
+ list(of_port_mod_prop_t) properties;
+};
+
+struct of_match_v3(align=8, length_includes_align=False) {
+ uint16_t type == 1;
+ uint16_t length;
+ list(of_oxm_t) oxm_list;
+};
+
+// This looks like an action header, but is standalone. See
+// ofp_table_features_prop_actions
+struct of_action_id {
+ uint16_t type;
+ uint16_t len;
+ of_octets_t exp_data;
+};
+
+struct of_action_output : of_action {
+ uint16_t type == 0;
+ uint16_t len;
+ of_port_no_t port;
+ uint16_t max_len;
+ pad(6);
+};
+
+struct of_action_copy_ttl_out : of_action {
+ uint16_t type == 11;
+ uint16_t len;
+ pad(4);
+};
+
+struct of_action_copy_ttl_in : of_action {
+ uint16_t type == 12;
+ uint16_t len;
+ pad(4);
+};
+
+struct of_action_set_mpls_ttl : of_action {
+ uint16_t type == 15;
+ uint16_t len;
+ uint8_t mpls_ttl;
+ pad(3);
+};
+
+struct of_action_dec_mpls_ttl : of_action {
+ uint16_t type == 16;
+ uint16_t len;
+ pad(4);
+};
+
+struct of_action_push_vlan : of_action {
+ uint16_t type == 17;
+ uint16_t len;
+ uint16_t ethertype;
+ pad(2);
+};
+
+struct of_action_pop_vlan : of_action {
+ uint16_t type == 18;
+ uint16_t len;
+ pad(4);
+};
+
+struct of_action_push_mpls : of_action {
+ uint16_t type == 19;
+ uint16_t len;
+ uint16_t ethertype;
+ pad(2);
+};
+
+struct of_action_pop_mpls : of_action {
+ uint16_t type == 20;
+ uint16_t len;
+ uint16_t ethertype;
+ pad(2);
+};
+
+struct of_action_set_queue : of_action {
+ uint16_t type == 21;
+ uint16_t len;
+ uint32_t queue_id;
+};
+
+struct of_action_group : of_action {
+ uint16_t type == 22;
+ uint16_t len;
+ uint32_t group_id;
+};
+
+struct of_action_set_nw_ttl : of_action {
+ uint16_t type == 23;
+ uint16_t len;
+ uint8_t nw_ttl;
+ pad(3);
+};
+
+struct of_action_dec_nw_ttl : of_action {
+ uint16_t type == 24;
+ uint16_t len;
+ pad(4);
+};
+
+struct of_action_set_field(align=8, length_includes_align=True) : of_action {
+ uint16_t type == 25;
+ uint16_t len;
+ of_oxm_t field;
+};
+
+struct of_action_experimenter(align=8, length_includes_align=True): of_action {
+ uint16_t type == 65535;
+ uint16_t len;
+ uint32_t experimenter == ?;
+ of_octets_t data;
+};
+
+struct of_action_pop_pbb : of_action {
+ uint16_t type == 27;
+ uint16_t len;
+ pad(4);
+};
+
+struct of_action_push_pbb : of_action {
+ uint16_t type == 26;
+ uint16_t len;
+ uint16_t ethertype;
+ pad(2);
+};
+
+struct of_action {
+ uint16_t type == ?;
+ uint16_t len;
+ pad(4);
+};
+
+struct of_instruction_id {
+ uint16_t type;
+ uint16_t len;
+};
+
+struct of_instruction {
+ uint16_t type == ?;
+ uint16_t len;
+};
+
+struct of_instruction_goto_table : of_instruction {
+ uint16_t type == 1;
+ uint16_t len;
+ uint8_t table_id;
+ pad(3);
+};
+
+struct of_instruction_write_metadata : of_instruction {
+ uint16_t type == 2;
+ uint16_t len;
+ pad(4);
+ uint64_t metadata;
+ uint64_t metadata_mask;
+};
+
+struct of_instruction_write_actions : of_instruction {
+ uint16_t type == 3;
+ uint16_t len;
+ pad(4);
+ list(of_action_t) actions;
+};
+
+struct of_instruction_apply_actions : of_instruction {
+ uint16_t type == 4;
+ uint16_t len;
+ pad(4);
+ list(of_action_t) actions;
+};
+
+struct of_instruction_clear_actions : of_instruction {
+ uint16_t type == 5;
+ uint16_t len;
+ pad(4);
+};
+
+struct of_instruction_meter : of_instruction {
+ uint16_t type == 6;
+ uint16_t len;
+ uint32_t meter_id;
+};
+
+struct of_instruction_experimenter : of_instruction {
+ uint16_t type == 65535;
+ uint16_t len;
+ uint32_t experimenter == ?;
+ of_octets_t data;
+};
+
+struct of_flow_mod : of_header {
+ uint8_t version;
+ uint8_t type == 14;
+ uint16_t length;
+ uint32_t xid;
+ uint64_t cookie;
+ uint64_t cookie_mask;
+ uint8_t table_id;
+ of_fm_cmd_t _command == ?;
+ uint16_t idle_timeout;
+ uint16_t hard_timeout;
+ uint16_t priority;
+ uint32_t buffer_id;
+ of_port_no_t out_port;
+ uint32_t out_group;
+ enum ofp_flow_mod_flags flags;
+ pad(2);
+ of_match_t match;
+ list(of_instruction_t) instructions;
+};
+
+struct of_flow_add : of_flow_mod {
+ uint8_t version;
+ uint8_t type == 14;
+ uint16_t length;
+ uint32_t xid;
+ uint64_t cookie;
+ uint64_t cookie_mask;
+ uint8_t table_id;
+ of_fm_cmd_t _command == 0;
+ uint16_t idle_timeout;
+ uint16_t hard_timeout;
+ uint16_t priority;
+ uint32_t buffer_id;
+ of_port_no_t out_port;
+ uint32_t out_group;
+ enum ofp_flow_mod_flags flags;
+ uint16_t importance;
+ of_match_t match;
+ list(of_instruction_t) instructions;
+};
+
+struct of_flow_modify : of_flow_mod {
+ uint8_t version;
+ uint8_t type == 14;
+ uint16_t length;
+ uint32_t xid;
+ uint64_t cookie;
+ uint64_t cookie_mask;
+ uint8_t table_id;
+ of_fm_cmd_t _command == 1;
+ uint16_t idle_timeout;
+ uint16_t hard_timeout;
+ uint16_t priority;
+ uint32_t buffer_id;
+ of_port_no_t out_port;
+ uint32_t out_group;
+ enum ofp_flow_mod_flags flags;
+ uint16_t importance;
+ of_match_t match;
+ list(of_instruction_t) instructions;
+};
+
+struct of_flow_modify_strict : of_flow_mod {
+ uint8_t version;
+ uint8_t type == 14;
+ uint16_t length;
+ uint32_t xid;
+ uint64_t cookie;
+ uint64_t cookie_mask;
+ uint8_t table_id;
+ of_fm_cmd_t _command == 2;
+ uint16_t idle_timeout;
+ uint16_t hard_timeout;
+ uint16_t priority;
+ uint32_t buffer_id;
+ of_port_no_t out_port;
+ uint32_t out_group;
+ enum ofp_flow_mod_flags flags;
+ uint16_t importance;
+ of_match_t match;
+ list(of_instruction_t) instructions;
+};
+
+struct of_flow_delete : of_flow_mod {
+ uint8_t version;
+ uint8_t type == 14;
+ uint16_t length;
+ uint32_t xid;
+ uint64_t cookie;
+ uint64_t cookie_mask;
+ uint8_t table_id;
+ of_fm_cmd_t _command == 3;
+ uint16_t idle_timeout;
+ uint16_t hard_timeout;
+ uint16_t priority;
+ uint32_t buffer_id;
+ of_port_no_t out_port;
+ uint32_t out_group;
+ enum ofp_flow_mod_flags flags;
+ uint16_t importance;
+ of_match_t match;
+ list(of_instruction_t) instructions;
+};
+
+struct of_flow_delete_strict : of_flow_mod {
+ uint8_t version;
+ uint8_t type == 14;
+ uint16_t length;
+ uint32_t xid;
+ uint64_t cookie;
+ uint64_t cookie_mask;
+ uint8_t table_id;
+ of_fm_cmd_t _command == 4;
+ uint16_t idle_timeout;
+ uint16_t hard_timeout;
+ uint16_t priority;
+ uint32_t buffer_id;
+ of_port_no_t out_port;
+ uint32_t out_group;
+ enum ofp_flow_mod_flags flags;
+ uint16_t importance;
+ of_match_t match;
+ list(of_instruction_t) instructions;
+};
+
+struct of_bucket {
+ uint16_t len;
+ uint16_t weight;
+ of_port_no_t watch_port;
+ uint32_t watch_group;
+ pad(4);
+ list(of_action_t) actions;
+};
+
+struct of_group_mod : of_header {
+ uint8_t version;
+ uint8_t type == 15;
+ uint16_t length;
+ uint32_t xid;
+ enum ofp_group_mod_command command == ?;
+ enum ofp_group_type group_type;
+ pad(1);
+ uint32_t group_id;
+ list(of_bucket_t) buckets;
+};
+
+struct of_group_add : of_group_mod {
+ uint8_t version;
+ uint8_t type == 15;
+ uint16_t length;
+ uint32_t xid;
+ enum ofp_group_mod_command command == 0;
+ enum ofp_group_type group_type;
+ pad(1);
+ uint32_t group_id;
+ list(of_bucket_t) buckets;
+};
+
+struct of_group_modify : of_group_mod {
+ uint8_t version;
+ uint8_t type == 15;
+ uint16_t length;
+ uint32_t xid;
+ enum ofp_group_mod_command command == 1;
+ enum ofp_group_type group_type;
+ pad(1);
+ uint32_t group_id;
+ list(of_bucket_t) buckets;
+};
+
+struct of_group_delete : of_group_mod {
+ uint8_t version;
+ uint8_t type == 15;
+ uint16_t length;
+ uint32_t xid;
+ enum ofp_group_mod_command command == 2;
+ enum ofp_group_type group_type;
+ pad(1);
+ uint32_t group_id;
+ list(of_bucket_t) buckets;
+};
+
+struct of_packet_out : of_header {
+ uint8_t version;
+ uint8_t type == 13;
+ uint16_t length;
+ uint32_t xid;
+ uint32_t buffer_id;
+ of_port_no_t in_port;
+ uint16_t actions_len;
+ pad(6);
+ list(of_action_t) actions;
+ of_octets_t data;
+};
+
+struct of_packet_in : of_header {
+ uint8_t version;
+ uint8_t type == 10;
+ uint16_t length;
+ uint32_t xid;
+ uint32_t buffer_id;
+ uint16_t total_len;
+ uint8_t reason;
+ uint8_t table_id;
+ uint64_t cookie;
+ of_match_t match;
+ pad(2);
+ of_octets_t data; /* FIXME: Ensure total_len gets updated */
+};
+
+struct of_flow_removed : of_header {
+ uint8_t version;
+ uint8_t type == 11;
+ uint16_t length;
+ uint32_t xid;
+ uint64_t cookie;
+ uint16_t priority;
+ uint8_t reason;
+ uint8_t table_id;
+ uint32_t duration_sec;
+ uint32_t duration_nsec;
+ uint16_t idle_timeout;
+ uint16_t hard_timeout;
+ uint64_t packet_count;
+ uint64_t byte_count;
+ of_match_t match;
+};
+
+struct of_meter_band {
+ uint16_t type == ?;
+ uint16_t len;
+// uint32_t rate; // These are excluded b/c this is the header
+// uint32_t burst_size; // These are excluded b/c this is the header
+};
+
+struct of_meter_band_drop : of_meter_band {
+ uint16_t type == 1;
+ uint16_t len;
+ uint32_t rate;
+ uint32_t burst_size;
+ pad(4);
+};
+
+struct of_meter_band_dscp_remark : of_meter_band {
+ uint16_t type == 2;
+ uint16_t len;
+ uint32_t rate;
+ uint32_t burst_size;
+ uint8_t prec_level;
+ pad(3);
+};
+
+struct of_meter_band_experimenter : of_meter_band {
+ uint16_t type == 65535;
+ uint16_t len;
+ uint32_t rate;
+ uint32_t burst_size;
+ uint32_t experimenter;
+};
+
+struct of_meter_mod : of_header {
+ uint8_t version;
+ uint8_t type == 29;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t command;
+ uint16_t flags;
+ uint32_t meter_id;
+ list(of_meter_band_t) bands;
+};
+
+struct of_error_msg : of_header {
+ uint8_t version;
+ uint8_t type == 1;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t err_type == ?;
+};
+
+struct of_hello_failed_error_msg : of_error_msg {
+ uint8_t version;
+ uint8_t type == 1;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t err_type == 0;
+ enum ofp_hello_failed_code code;
+ of_octets_t data;
+};
+
+struct of_bad_request_error_msg : of_error_msg {
+ uint8_t version;
+ uint8_t type == 1;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t err_type == 1;
+ enum ofp_bad_request_code code;
+ of_octets_t data;
+};
+
+struct of_bad_action_error_msg : of_error_msg {
+ uint8_t version;
+ uint8_t type == 1;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t err_type == 2;
+ enum ofp_bad_action_code code;
+ of_octets_t data;
+};
+
+struct of_bad_instruction_error_msg : of_error_msg {
+ uint8_t version;
+ uint8_t type == 1;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t err_type == 3;
+ enum ofp_bad_instruction_code code;
+ of_octets_t data;
+};
+
+struct of_bad_match_error_msg : of_error_msg {
+ uint8_t version;
+ uint8_t type == 1;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t err_type == 4;
+ enum ofp_bad_match_code code;
+ of_octets_t data;
+};
+
+struct of_flow_mod_failed_error_msg : of_error_msg {
+ uint8_t version;
+ uint8_t type == 1;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t err_type == 5;
+ enum ofp_flow_mod_failed_code code;
+ of_octets_t data;
+};
+
+struct of_group_mod_failed_error_msg : of_error_msg {
+ uint8_t version;
+ uint8_t type == 1;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t err_type == 6;
+ enum ofp_group_mod_failed_code code;
+ of_octets_t data;
+};
+
+struct of_port_mod_failed_error_msg : of_error_msg {
+ uint8_t version;
+ uint8_t type == 1;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t err_type == 7;
+ enum ofp_port_mod_failed_code code;
+ of_octets_t data;
+};
+
+struct of_table_mod_failed_error_msg : of_error_msg {
+ uint8_t version;
+ uint8_t type == 1;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t err_type == 8;
+ enum ofp_table_mod_failed_code code;
+ of_octets_t data;
+};
+
+struct of_queue_op_failed_error_msg : of_error_msg {
+ uint8_t version;
+ uint8_t type == 1;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t err_type == 9;
+ enum ofp_queue_op_failed_code code;
+ of_octets_t data;
+};
+
+struct of_switch_config_failed_error_msg : of_error_msg {
+ uint8_t version;
+ uint8_t type == 1;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t err_type == 10;
+ enum ofp_switch_config_failed_code code;
+ of_octets_t data;
+};
+
+struct of_role_request_failed_error_msg : of_error_msg {
+ uint8_t version;
+ uint8_t type == 1;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t err_type == 11;
+ enum ofp_role_request_failed_code code;
+ of_octets_t data;
+};
+
+struct of_meter_mod_failed_error_msg : of_error_msg {
+ uint8_t version;
+ uint8_t type == 1;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t err_type == 12;
+ enum ofp_meter_mod_failed_code code;
+ of_octets_t data;
+};
+
+struct of_table_features_failed_error_msg : of_error_msg {
+ uint8_t version;
+ uint8_t type == 1;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t err_type == 13;
+ enum ofp_table_features_failed_code code;
+ of_octets_t data;
+};
+
+struct of_experimenter_error_msg : of_error_msg {
+ uint8_t version;
+ uint8_t type == 1;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t err_type == 0xffff;
+ uint16_t subtype;
+ uint32_t experimenter;
+ of_octets_t data;
+};
+
+// STATS ENTRIES: flow, table, port, queue, group stats, group desc stats
+
+struct of_flow_stats_entry {
+ uint16_t length;
+ uint8_t table_id;
+ pad(1);
+ uint32_t duration_sec;
+ uint32_t duration_nsec;
+ uint16_t priority;
+ uint16_t idle_timeout;
+ uint16_t hard_timeout;
+ enum ofp_flow_mod_flags flags;
+ uint16_t importance;
+ pad(2);
+ uint64_t cookie;
+ uint64_t packet_count;
+ uint64_t byte_count;
+ of_match_t match;
+ list(of_instruction_t) instructions;
+};
+
+
+struct of_table_stats_entry {
+ uint8_t table_id;
+ pad(3);
+ uint32_t active_count;
+ uint64_t lookup_count;
+ uint64_t matched_count;
+};
+
+/* Common header for all port stats properties. */
+struct of_port_stats_prop {
+ uint16_t type == ?; /* One of OFPPSPT_*. */
+ uint16_t length; /* Length in bytes of this property. */
+};
+
+/* Ethernet port stats property. */
+struct of_port_stats_prop_ethernet : of_port_stats_prop {
+ uint16_t type == 0; /* OFPPSPT_ETHERNET. */
+ uint16_t length; /* Length in bytes of this property. */
+ pad(4);
+
+ uint64_t rx_frame_err; /* Number of frame alignment errors. */
+ uint64_t rx_over_err; /* Number of packets with RX overrun. */
+ uint64_t rx_crc_err; /* Number of CRC errors. */
+ uint64_t collisions; /* Number of collisions. */
+};
+
+/* Optical port stats property. */
+struct of_port_stats_prop_optical : of_port_stats_prop {
+ uint16_t type == 1;
+ uint16_t length;
+ pad(4);
+
+ uint32_t flags;
+ uint32_t tx_freq_lmda;
+ uint32_t tx_offset;
+ uint32_t tx_grid_span;
+ uint32_t rx_freq_lmda;
+ uint32_t rx_offset;
+ uint32_t rx_grid_span;
+ uint16_t tx_pwr;
+ uint16_t rx_pwr;
+ uint16_t bias_current;
+ uint16_t temperature;
+};
+
+/* Experimenter port stats property. */
+struct of_port_stats_prop_experimenter : of_port_stats_prop {
+ uint16_t type == 0xffff;
+ uint16_t length;
+ uint32_t experimenter == ?;
+ uint32_t exp_type;
+ of_octets_t experimenter_data;
+};
+
+struct of_port_stats_entry {
+ uint16_t length;
+ pad(2);
+ of_port_no_t port_no;
+ uint32_t duration_sec;
+ uint32_t duration_nsec;
+ uint64_t rx_packets;
+ uint64_t tx_packets;
+ uint64_t rx_bytes;
+ uint64_t tx_bytes;
+ uint64_t rx_dropped;
+ uint64_t tx_dropped;
+ uint64_t rx_errors;
+ uint64_t tx_errors;
+ list(of_port_stats_prop_t) properties;
+};
+
+struct of_queue_stats_prop {
+ uint16_t type == ?;
+ uint16_t length;
+};
+
+struct of_queue_stats_entry {
+ uint16_t length;
+ pad(6);
+ of_port_no_t port_no;
+ uint32_t queue_id;
+ uint64_t tx_bytes;
+ uint64_t tx_packets;
+ uint64_t tx_errors;
+ uint32_t duration_sec;
+ uint32_t duration_nsec;
+
+
+ list(of_queue_stats_prop_t) properties;
+};
+
+struct of_bucket_counter {
+ uint64_t packet_count;
+ uint64_t byte_count;
+};
+
+struct of_group_stats_entry {
+ uint16_t length;
+ pad(2);
+ uint32_t group_id;
+ uint32_t ref_count;
+ pad(4);
+ uint64_t packet_count;
+ uint64_t byte_count;
+ uint32_t duration_sec;
+ uint32_t duration_nsec;
+ list(of_bucket_counter_t) bucket_stats;
+};
+
+struct of_group_desc_stats_entry {
+ uint16_t length;
+ enum ofp_group_type group_type;
+ pad(1);
+ uint32_t group_id;
+ list(of_bucket_t) buckets;
+};
+
+// STATS:
+// Desc, flow, agg, table, port, queue, group, group_desc, group_feat, experi
+
+struct of_stats_request : of_header {
+ uint8_t version;
+ uint8_t type == 18;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == ?;
+ enum ofp_stats_request_flags flags;
+ pad(4);
+};
+
+struct of_stats_reply : of_header {
+ uint8_t version;
+ uint8_t type == 19;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == ?;
+ enum ofp_stats_reply_flags flags;
+ pad(4);
+};
+
+struct of_desc_stats_request : of_stats_request {
+ uint8_t version;
+ uint8_t type == 18;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 0;
+ enum ofp_stats_request_flags flags;
+ pad(4);
+};
+
+struct of_desc_stats_reply : of_stats_reply {
+ uint8_t version;
+ uint8_t type == 19;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 0;
+ enum ofp_stats_reply_flags flags;
+ pad(4);
+ of_desc_str_t mfr_desc;
+ of_desc_str_t hw_desc;
+ of_desc_str_t sw_desc;
+ of_serial_num_t serial_num;
+ of_desc_str_t dp_desc;
+};
+
+struct of_flow_stats_request : of_stats_request {
+ uint8_t version;
+ uint8_t type == 18;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 1;
+ enum ofp_stats_request_flags flags;
+ pad(4);
+ uint8_t table_id;
+ pad(3);
+ of_port_no_t out_port;
+ uint32_t out_group;
+ pad(4);
+ uint64_t cookie;
+ uint64_t cookie_mask;
+ of_match_t match;
+};
+
+struct of_flow_stats_reply : of_stats_reply {
+ uint8_t version;
+ uint8_t type == 19;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 1;
+ enum ofp_stats_reply_flags flags;
+ pad(4);
+ list(of_flow_stats_entry_t) entries;
+};
+
+struct of_aggregate_stats_request : of_stats_request {
+ uint8_t version;
+ uint8_t type == 18;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 2;
+ enum ofp_stats_request_flags flags;
+ pad(4);
+ uint8_t table_id;
+ pad(3);
+ of_port_no_t out_port;
+ uint32_t out_group;
+ pad(4);
+ uint64_t cookie;
+ uint64_t cookie_mask;
+ of_match_t match;
+};
+
+struct of_aggregate_stats_reply : of_stats_reply {
+ uint8_t version;
+ uint8_t type == 19;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 2;
+ enum ofp_stats_reply_flags flags;
+ pad(4);
+ uint64_t packet_count;
+ uint64_t byte_count;
+ uint32_t flow_count;
+ pad(4);
+};
+
+struct of_table_stats_request : of_stats_request {
+ uint8_t version;
+ uint8_t type == 18;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 3;
+ enum ofp_stats_request_flags flags;
+ pad(4);
+};
+
+struct of_table_stats_reply : of_stats_reply {
+ uint8_t version;
+ uint8_t type == 19;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 3;
+ enum ofp_stats_reply_flags flags;
+ pad(4);
+ list(of_table_stats_entry_t) entries;
+};
+
+struct of_experimenter_stats_request : of_stats_request {
+ uint8_t version;
+ uint8_t type == 18;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 0xffff;
+ enum ofp_stats_request_flags flags;
+ pad(4);
+ uint32_t experimenter == ?;
+ uint32_t subtype;
+};
+
+struct of_experimenter_stats_reply : of_stats_reply {
+ uint8_t version;
+ uint8_t type == 19;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 0xffff;
+ enum ofp_stats_reply_flags flags;
+ pad(4);
+ uint32_t experimenter == ?;
+ uint32_t subtype;
+};
+
+// FIXME: These are padded to 8 byte align beyond the length indicated
+
+struct of_table_feature_prop {
+ uint16_t type == ?;
+ uint16_t length;
+};
+
+struct of_table_feature_prop_instructions : of_table_feature_prop {
+ uint16_t type == 0;
+ uint16_t length;
+ // FIXME Check if instruction_t is right for ids here
+ list(of_instruction_id_t) instruction_ids;
+};
+
+struct of_table_feature_prop_instructions_miss : of_table_feature_prop {
+ uint16_t type == 1;
+ uint16_t length;
+ list(of_instruction_id_t) instruction_ids;
+};
+
+struct of_table_feature_prop_next_tables : of_table_feature_prop {
+ uint16_t type == 2;
+ uint16_t length;
+ list(of_uint8_t) next_table_ids;
+};
+
+struct of_table_feature_prop_next_tables_miss : of_table_feature_prop {
+ uint16_t type == 3;
+ uint16_t length;
+ list(of_uint8_t) next_table_ids;
+};
+
+struct of_table_feature_prop_write_actions : of_table_feature_prop {
+ uint16_t type == 4;
+ uint16_t length;
+ list(of_action_id_t) action_ids;
+};
+
+struct of_table_feature_prop_write_actions_miss : of_table_feature_prop {
+ uint16_t type == 5;
+ uint16_t length;
+ list(of_action_id_t) action_ids;
+};
+
+struct of_table_feature_prop_apply_actions : of_table_feature_prop {
+ uint16_t type == 6;
+ uint16_t length;
+ list(of_action_id_t) action_ids;
+};
+
+struct of_table_feature_prop_apply_actions_miss : of_table_feature_prop {
+ uint16_t type == 7;
+ uint16_t length;
+ list(of_action_id_t) action_ids;
+};
+
+struct of_table_feature_prop_match : of_table_feature_prop {
+ uint16_t type == 8;
+ uint16_t length;
+ list(of_uint32_t) oxm_ids;
+};
+
+struct of_table_feature_prop_wildcards : of_table_feature_prop {
+ uint16_t type == 10;
+ uint16_t length;
+ list(of_uint32_t) oxm_ids;
+};
+
+struct of_table_feature_prop_write_setfield : of_table_feature_prop {
+ uint16_t type == 12;
+ uint16_t length;
+ list(of_uint32_t) oxm_ids;
+};
+
+struct of_table_feature_prop_write_setfield_miss : of_table_feature_prop {
+ uint16_t type == 13;
+ uint16_t length;
+ list(of_uint32_t) oxm_ids;
+};
+
+struct of_table_feature_prop_apply_setfield : of_table_feature_prop {
+ uint16_t type == 14;
+ uint16_t length;
+ list(of_uint32_t) oxm_ids;
+};
+
+struct of_table_feature_prop_apply_setfield_miss : of_table_feature_prop {
+ uint16_t type == 15;
+ uint16_t length;
+ list(of_uint32_t) oxm_ids;
+};
+
+struct of_table_feature_prop_experimenter : of_table_feature_prop {
+ uint16_t type == 65534;
+ uint16_t length;
+ uint32_t experimenter == ?;
+ uint32_t subtype;
+ of_octets_t experimenter_data;
+};
+
+struct of_table_feature_prop_experimenter_miss : of_table_feature_prop {
+ uint16_t type == 65535;
+ uint16_t length;
+ uint32_t experimenter == ?;
+ uint32_t subtype;
+ of_octets_t experimenter_data;
+};
+
+struct of_table_features {
+ uint16_t length;
+ uint8_t table_id;
+ pad(5);
+ of_table_name_t name;
+ uint64_t metadata_match;
+ uint64_t metadata_write;
+ uint32_t config;
+ uint32_t max_entries;
+ list(of_table_feature_prop_t) properties;
+};
+
+struct of_meter_features {
+ uint32_t max_meter;
+ uint32_t band_types;
+ uint32_t capabilities;
+ uint8_t max_bands;
+ uint8_t max_color;
+ pad(2);
+};
+
+struct of_port_stats_request : of_stats_request {
+ uint8_t version;
+ uint8_t type == 18;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 4;
+ enum ofp_stats_request_flags flags;
+ pad(4);
+ of_port_no_t port_no;
+ pad(4);
+};
+
+struct of_port_stats_reply : of_stats_reply {
+ uint8_t version;
+ uint8_t type == 19;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 4;
+ enum ofp_stats_reply_flags flags;
+ pad(4);
+ list(of_port_stats_entry_t) entries;
+};
+
+struct of_queue_stats_request : of_stats_request {
+ uint8_t version;
+ uint8_t type == 18;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 5;
+ enum ofp_stats_request_flags flags;
+ pad(4);
+ of_port_no_t port_no;
+ uint32_t queue_id;
+};
+
+struct of_queue_stats_reply : of_stats_reply {
+ uint8_t version;
+ uint8_t type == 19;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 5;
+ enum ofp_stats_reply_flags flags;
+ pad(4);
+ list(of_queue_stats_entry_t) entries;
+};
+
+struct of_group_stats_request : of_stats_request {
+ uint8_t version;
+ uint8_t type == 18;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 6;
+ enum ofp_stats_request_flags flags;
+ pad(4);
+ uint32_t group_id;
+ pad(4);
+};
+
+struct of_group_stats_reply : of_stats_reply {
+ uint8_t version;
+ uint8_t type == 19;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 6;
+ enum ofp_stats_reply_flags flags;
+ pad(4);
+ list(of_group_stats_entry_t) entries;
+};
+
+struct of_group_desc_stats_request : of_stats_request {
+ uint8_t version;
+ uint8_t type == 18;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 7;
+ enum ofp_stats_request_flags flags;
+ pad(4);
+};
+
+struct of_group_desc_stats_reply : of_stats_reply {
+ uint8_t version;
+ uint8_t type == 19;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 7;
+ enum ofp_stats_reply_flags flags;
+ pad(4);
+ list(of_group_desc_stats_entry_t) entries;
+};
+
+struct of_group_features_stats_request : of_stats_request {
+ uint8_t version;
+ uint8_t type == 18;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 8;
+ enum ofp_stats_request_flags flags;
+ pad(4);
+};
+
+struct of_group_features_stats_reply : of_stats_reply {
+ uint8_t version;
+ uint8_t type == 19;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 8;
+ enum ofp_stats_reply_flags flags;
+ pad(4);
+ uint32_t types;
+ uint32_t capabilities;
+ uint32_t max_groups_all;
+ uint32_t max_groups_select;
+ uint32_t max_groups_indirect;
+ uint32_t max_groups_ff;
+ uint32_t actions_all;
+ uint32_t actions_select;
+ uint32_t actions_indirect;
+ uint32_t actions_ff;
+};
+
+struct of_meter_stats_request : of_stats_request {
+ uint8_t version;
+ uint8_t type == 18;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 9;
+ enum ofp_stats_request_flags flags;
+ pad(4);
+ uint32_t meter_id;
+ pad(4);
+};
+
+struct of_meter_stats_reply : of_stats_reply {
+ uint8_t version;
+ uint8_t type == 19;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 9;
+ enum ofp_stats_reply_flags flags;
+ pad(4);
+ list(of_meter_stats_t) entries;
+};
+
+struct of_meter_config_stats_request : of_stats_request {
+ uint8_t version;
+ uint8_t type == 18;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 10;
+ enum ofp_stats_request_flags flags;
+ pad(4);
+ uint32_t meter_id;
+ pad(4);
+};
+
+struct of_meter_config_stats_reply : of_stats_reply {
+ uint8_t version;
+ uint8_t type == 19;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 10;
+ enum ofp_stats_reply_flags flags;
+ pad(4);
+ list(of_meter_band_t) entries;
+};
+
+// FIXME stats added to get things working
+struct of_meter_features_stats_request : of_stats_request {
+ uint8_t version;
+ uint8_t type == 18;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 11;
+ enum ofp_stats_request_flags flags;
+ pad(4);
+};
+
+// FIXME stats added to get things working
+struct of_meter_features_stats_reply : of_stats_reply {
+ uint8_t version;
+ uint8_t type == 19;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 11;
+ enum ofp_stats_reply_flags flags;
+ pad(4);
+ of_meter_features_t features;
+};
+
+// FIXME stats added to get things working
+struct of_table_features_stats_request : of_stats_request {
+ uint8_t version;
+ uint8_t type == 18;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 12;
+ enum ofp_stats_request_flags flags;
+ pad(4);
+ list(of_table_features_t) entries;
+};
+
+// FIXME stats added to get things working
+struct of_table_features_stats_reply : of_stats_reply {
+ uint8_t version;
+ uint8_t type == 19;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 12;
+ enum ofp_stats_reply_flags flags;
+ pad(4);
+ list(of_table_features_t) entries;
+};
+
+// FIXME stats added to get things working
+struct of_port_desc_stats_request : of_stats_request {
+ uint8_t version;
+ uint8_t type == 18;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 13;
+ enum ofp_stats_request_flags flags;
+ pad(4);
+};
+
+// FIXME stats added to get things working
+struct of_port_desc_stats_reply : of_stats_reply {
+ uint8_t version;
+ uint8_t type == 19;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 13;
+ enum ofp_stats_reply_flags flags;
+ pad(4);
+ list(of_port_desc_t) entries;
+};
+
+struct of_meter_band_stats {
+ uint64_t packet_band_count;
+ uint64_t byte_band_count;
+};
+
+struct of_meter_stats {
+ uint32_t meter_id;
+ uint16_t len;
+ pad(6);
+ uint32_t flow_count;
+ uint64_t packet_in_count;
+ uint64_t byte_in_count;
+ uint32_t duration_sec;
+ uint32_t duration_nsec;
+ list(of_meter_band_stats_t) band_stats;
+};
+
+struct of_meter_config {
+ uint16_t length;
+ uint16_t flags;
+ uint32_t meter_id;
+ list(of_meter_band_t) entries;
+};
+
+// END OF STATS OBJECTS
+
+struct of_queue_prop {
+ uint16_t type == ?;
+ uint16_t len;
+ pad(4);
+};
+
+struct of_queue_prop_min_rate : of_queue_prop {
+ uint16_t type == 1;
+ uint16_t len;
+ pad(4);
+ uint16_t rate;
+ pad(6);
+};
+
+struct of_queue_prop_max_rate : of_queue_prop {
+ uint16_t type == 2;
+ uint16_t len;
+ pad(4);
+ uint16_t rate;
+ pad(6);
+};
+
+struct of_queue_prop_experimenter : of_queue_prop {
+ uint16_t type == 65535;
+ uint16_t len;
+ pad(4);
+ uint32_t experimenter == ?;
+ pad(4);
+ of_octets_t data;
+};
+
+struct of_packet_queue {
+ uint32_t queue_id;
+ of_port_no_t port;
+ uint16_t len;
+ pad(6);
+ list(of_queue_prop_t) properties;
+};
+
+struct of_role_request : of_header {
+ uint8_t version;
+ uint8_t type == 24;
+ uint16_t length;
+ uint32_t xid;
+ enum ofp_controller_role role;
+ pad(4);
+ uint64_t generation_id;
+};
+
+struct of_role_reply : of_header {
+ uint8_t version;
+ uint8_t type == 25;
+ uint16_t length;
+ uint32_t xid;
+ enum ofp_controller_role role;
+ pad(4);
+ uint64_t generation_id;
+};
+
+////////////////////////////////////////////////////////////////
+// FIXME understand async; where do bitmasks live?
+// Determine bitmap type for masks below.
+// DOCUMENT masks where uint32_t[0] is interest for equal/master
+// while uint32_t[1] is interest for slave
+////////////////////////////////////////////////////////////////
+
+struct of_async_get_request : of_header {
+ uint8_t version;
+ uint8_t type == 26;
+ uint16_t length;
+ uint32_t xid;
+ uint32_t packet_in_mask_equal_master;
+ uint32_t packet_in_mask_slave;
+ uint32_t port_status_mask_equal_master;
+ uint32_t port_status_mask_slave;
+ uint32_t flow_removed_mask_equal_master;
+ uint32_t flow_removed_mask_slave;
+};
+
+struct of_async_get_reply : of_header {
+ uint8_t version;
+ uint8_t type == 27;
+ uint16_t length;
+ uint32_t xid;
+ uint32_t packet_in_mask_equal_master;
+ uint32_t packet_in_mask_slave;
+ uint32_t port_status_mask_equal_master;
+ uint32_t port_status_mask_slave;
+ uint32_t flow_removed_mask_equal_master;
+ uint32_t flow_removed_mask_slave;
+};
+
+struct of_async_set : of_header {
+ uint8_t version;
+ uint8_t type == 28;
+ uint16_t length;
+ uint32_t xid;
+ uint32_t packet_in_mask_equal_master;
+ uint32_t packet_in_mask_slave;
+ uint32_t port_status_mask_equal_master;
+ uint32_t port_status_mask_slave;
+ uint32_t flow_removed_mask_equal_master;
+ uint32_t flow_removed_mask_slave;
+};
diff --git a/py_gen/codegen.py b/py_gen/codegen.py
index 3b0988e..a664d87 100644
--- a/py_gen/codegen.py
+++ b/py_gen/codegen.py
@@ -43,6 +43,12 @@
'of_instruction_id': 'instruction_id',
'of_meter_band': 'meter_band',
'of_bsn_tlv': 'bsn_tlv',
+ 'of_port_desc_prop': 'port_desc_prop',
+ 'of_port_stats_prop': 'port_stats_prop',
+ 'of_port_mod_prop': 'port_mod_prop',
+ 'of_table_mod_prop': 'table_mod_prop',
+ 'of_queue_desc_prop': 'queue_desc_prop',
+ 'of_queue_stats_prop': 'queue_stats_prop',
}
# Return the module and class names for the generated Python class
diff --git a/py_gen/templates/_common_extra.py b/py_gen/templates/_common_extra.py
index 8639dc4..f801965 100644
--- a/py_gen/templates/_common_extra.py
+++ b/py_gen/templates/_common_extra.py
@@ -35,4 +35,7 @@
:: elif version == OFVersions.VERSION_1_3:
:: # HACK
match = match_v3
+:: elif version == OFVersions.VERSION_1_4:
+:: # HACK
+match = match_v3
:: #endif
diff --git a/py_gen/templates/toplevel_init.py b/py_gen/templates/toplevel_init.py
index e5493a5..0393169 100644
--- a/py_gen/templates/toplevel_init.py
+++ b/py_gen/templates/toplevel_init.py
@@ -39,20 +39,13 @@
"""
Import and return the protocol module for the given wire version.
"""
- if ver == 1:
- import of10
- return of10
- elif ver == 2:
- import of11
- return of11
- elif ver == 3:
- import of12
- return of12
- elif ver == 4:
- import of13
- return of13
- else:
- raise ValueError
+:: for v in loxi_globals.OFVersions.all_supported:
+ if ver == ${v.wire_version}:
+ import of${v.version.replace('.', '')}
+ return of${v.version.replace('.', '')}
+
+:: #endfor
+ raise ValueError
class ProtocolError(Exception):
"""
diff --git a/py_gen/tests/of14.py b/py_gen/tests/of14.py
new file mode 100644
index 0000000..3fdfb8e
--- /dev/null
+++ b/py_gen/tests/of14.py
@@ -0,0 +1,130 @@
+#!/usr/bin/env python
+# Copyright 2014, Big Switch Networks, Inc.
+#
+# LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
+# the following special exception:
+#
+# LOXI Exception
+#
+# As a special exception to the terms of the EPL, you may distribute libraries
+# generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
+# that copyright and licensing notices generated by LoxiGen are not altered or removed
+# from the LoxiGen Libraries and the notice provided below is (i) included in
+# the LoxiGen Libraries, if distributed in source code form and (ii) included in any
+# documentation for the LoxiGen Libraries, if distributed in binary form.
+#
+# Notice: "Copyright 2014, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
+#
+# You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
+# a copy of the EPL at:
+#
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# EPL for the specific language governing permissions and limitations
+# under the EPL.
+import unittest
+from testutil import test_serialization
+from testutil import add_datafiles_tests
+
+try:
+ import loxi
+ import loxi.of14 as ofp
+ from loxi.generic_util import OFReader
+except ImportError:
+ exit("loxi package not found. Try setting PYTHONPATH.")
+
+class TestImports(unittest.TestCase):
+ def test_toplevel(self):
+ import loxi
+ self.assertTrue(hasattr(loxi, "ProtocolError"))
+ self.assertEquals(loxi.version_names[5], "1.4")
+ ofp = loxi.protocol(5)
+ self.assertEquals(ofp.OFP_VERSION, 5)
+ self.assertTrue(hasattr(ofp, "action"))
+ self.assertTrue(hasattr(ofp, "common"))
+ self.assertTrue(hasattr(ofp, "const"))
+ self.assertTrue(hasattr(ofp, "message"))
+ self.assertTrue(hasattr(ofp, "oxm"))
+
+ def test_version(self):
+ import loxi
+ self.assertTrue(hasattr(loxi.of14, "ProtocolError"))
+ self.assertTrue(hasattr(loxi.of14, "OFP_VERSION"))
+ self.assertEquals(loxi.of14.OFP_VERSION, 5)
+ self.assertTrue(hasattr(loxi.of14, "action"))
+ self.assertTrue(hasattr(loxi.of14, "common"))
+ self.assertTrue(hasattr(loxi.of14, "const"))
+ self.assertTrue(hasattr(loxi.of14, "message"))
+ self.assertTrue(hasattr(loxi.of14, "oxm"))
+
+# The majority of the serialization tests are created here using the files in
+# the test_data directory.
+class TestDataFiles(unittest.TestCase):
+ pass
+add_datafiles_tests(TestDataFiles, 'of14/', ofp)
+
+class TestAllof14(unittest.TestCase):
+ """
+ Round-trips every class through serialization/deserialization.
+ Not a replacement for handcoded tests because it only uses the
+ default member values.
+ """
+
+ def setUp(self):
+ mods = [ofp.action,ofp.message,ofp.common,ofp.oxm]
+ self.klasses = [klass for mod in mods
+ for klass in mod.__dict__.values()
+ if isinstance(klass, type) and
+ issubclass(klass, loxi.OFObject) and
+ not hasattr(klass, 'subtypes')]
+ self.klasses.sort(key=lambda x: str(x))
+
+ def test_serialization(self):
+ expected_failures = [
+ ofp.action.set_field, # field defaults to None
+ ]
+ for klass in self.klasses:
+ def fn():
+ obj = klass()
+ if hasattr(obj, "xid"): obj.xid = 42
+ buf = obj.pack()
+ obj2 = klass.unpack(OFReader(buf))
+ self.assertEquals(obj, obj2)
+ if klass in expected_failures:
+ self.assertRaises(Exception, fn)
+ else:
+ fn()
+
+ def test_parse_message(self):
+ expected_failures = [
+ ]
+ for klass in self.klasses:
+ if not issubclass(klass, ofp.message.message):
+ continue
+ def fn():
+ obj = klass(xid=42)
+ buf = obj.pack()
+ obj2 = ofp.message.parse_message(buf)
+ self.assertEquals(obj, obj2)
+ if klass in expected_failures:
+ self.assertRaises(Exception, fn)
+ else:
+ fn()
+
+ def test_show(self):
+ expected_failures = []
+ for klass in self.klasses:
+ def fn():
+ obj = klass()
+ if hasattr(obj, "xid"): obj.xid = 42
+ obj.show()
+ if klass in expected_failures:
+ self.assertRaises(Exception, fn)
+ else:
+ fn()
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/test_data/of14/flow_add.data b/test_data/of14/flow_add.data
new file mode 100644
index 0000000..88cf939
--- /dev/null
+++ b/test_data/of14/flow_add.data
@@ -0,0 +1,104 @@
+-- binary
+05 0e # version, type
+00 80 # length
+12 34 56 78 # xid
+
+fe dc ba 98 76 54 32 10 # cookie
+
+ff 00 ff 00 ff 00 ff 00 # cookie_mask
+
+03 # table_id
+00 # _command
+00 05 # idle_timeout
+00 0a # hard_timeout
+17 70 # priority
+
+00 00 00 32 # buffer_id
+00 00 00 06 # out_port
+
+00 00 00 08 # out_group
+00 00 # flags
+aa bb # importance
+
+00 01 # match.type
+00 3F # match.length # 59 bytes OXMs + 4 bytes match header
+
+80 00 01 08 # match.oxm_list[0].type_len - IN_PORT
+00 00 00 04 # match.oxm_list[0].value
+00 00 00 05 # match.oxm_list[0].mask
+
+80 00 0A 02 # match.oxm_list[1].type_len - ETH_TYPE
+86 DD # match.oxm_list[1].value - ETH_TYPE = IPv6
+
+80 00 14 01 # match.oxm_list[2].type_len - IP Proto
+06 # match.oxm_list[2].value = IP_PROTO = TCP
+
+80 00 35 20 # match.oxm_list[3].type_len - IPV6_SRC
+1C CA FE 1C B1 10 1C 00 00 28 00 00 00 00 00 00 # match.oxm_list[3].value
+FF FF FF FF FF F0 FF FF 1C 2C 3C 00 00 00 00 00 # match.oxm_list[3].mask
+
+00 # match.pad
+
+00 01 # instructions[0].type
+00 08 # instructions[0].length
+04 # instructions[0].table_id
+00 00 00 # pad
+
+00 01 # instructions[1].type
+00 08 # instructions[1].length
+07 # instructions[1].table_id
+00 00 00 # pad
+-- python
+ofp.message.flow_add(
+ xid=0x12345678,
+ cookie=0xFEDCBA9876543210,
+ cookie_mask=0xFF00FF00FF00FF00,
+ table_id=3,
+ idle_timeout=5,
+ hard_timeout=10,
+ priority=6000,
+ buffer_id=50,
+ out_port=6,
+ out_group=8,
+ flags=0,
+ importance=0xaabb,
+ match=ofp.match(oxm_list=[
+ ofp.oxm.in_port_masked(value=4, value_mask=5),
+ ofp.oxm.eth_type(value=0x86dd),
+ ofp.oxm.ip_proto(value=6),
+ ofp.oxm.ipv6_src_masked(
+ value ='\x1C\xCA\xFE\x1C\xB1\x10\x1C\x00\x00\x28\x00\x00\x00\x00\x00\x00',
+ value_mask='\xFF\xFF\xFF\xFF\xFF\xF0\xFF\xFF\x1C\x2C\x3C\x00\x00\x00\x00\x00')
+ ]),
+ instructions=[
+ ofp.instruction.goto_table(table_id=4),
+ ofp.instruction.goto_table(table_id=7)])
+-- java
+builder.setXid(0x12345678)
+ .setCookie(U64.parseHex("FEDCBA9876543210"))
+ .setCookieMask(U64.parseHex("FF00FF00FF00FF00"))
+ .setTableId(TableId.of(3))
+ .setIdleTimeout(5)
+ .setHardTimeout(10)
+ .setPriority(6000)
+ .setBufferId(OFBufferId.of(50))
+ .setOutPort(OFPort.of(6))
+ .setOutGroup(OFGroup.of(8))
+ .setFlags(ImmutableSet.<OFFlowModFlags>of())
+ .setImportance(0xaabb)
+ .setMatch(
+ factory.buildMatch()
+ .setMasked(MatchField.IN_PORT, OFPort.of(4), OFPort.of(5))
+ .setExact(MatchField.ETH_TYPE, EthType.IPv6)
+ .setExact(MatchField.IP_PROTO, IpProtocol.TCP)
+ .setMasked(MatchField.IPV6_SRC,
+ IPv6Address.of(0x1CCAFE1CB1101C00l, 0x0028000000000000l),
+ IPv6Address.of(0xFFFFFFFFFFF0FFFFl, 0x1C2C3C0000000000l))
+ .build()
+ )
+ .setInstructions(
+ ImmutableList.<OFInstruction>of(
+ factory.instructions().gotoTable(TableId.of(4)),
+ factory.instructions().gotoTable(TableId.of(7))
+ )
+ );
diff --git a/test_data/of14/port_desc_stats_reply.data b/test_data/of14/port_desc_stats_reply.data
new file mode 100644
index 0000000..8e38975
--- /dev/null
+++ b/test_data/of14/port_desc_stats_reply.data
@@ -0,0 +1,54 @@
+-- binary
+05 13 # version/type
+00 58 # length
+00 00 00 05 # xid
+00 0d # stats_type
+00 00 # flags
+00 00 00 00 # pad
+00 00 00 01 # entries[0].port_no
+00 48 # entries[0].length
+00 00 # pad
+01 02 03 04 05 06 # entries[0].hw_addr
+00 00 # pad
+69 6e 74 65 72 66 61 63 65 31 32 33 34 35 36 37 # entries[0].name
+00 00 00 60 # entries[0].config
+00 00 00 03 # entries[0].state
+00 00 # entries[0].properties[0].type (ethernet)
+00 20 # entries[0].properties[0].length
+00 00 00 00 # pad
+00 00 00 70 # entries[0].properties[0].curr
+00 00 00 00 # entries[0].properties[0].advertised
+00 00 00 00 # entries[0].properties[0].supported
+00 00 00 00 # entries[0].properties[0].peer
+00 00 00 00 # entries[0].properties[0].curr_speed
+00 00 00 80 # entries[0].properties[0].max_speed
+-- python
+ofp.message.port_desc_stats_reply(
+ xid=5, flags=0, entries=[
+ ofp.port_desc(
+ port_no=1,
+ hw_addr=[1,2,3,4,5,6],
+ name="interface1234567",
+ config=0x60,
+ state=0x03,
+ properties=[
+ ofp.port_desc_prop.ethernet(
+ curr=0x70,
+ max_speed=0x80)])])
+-- java
+builder
+ .setXid(5)
+ .setFlags(ImmutableSet.<OFStatsReplyFlags>of())
+ .setEntries(ImmutableList.of(
+ factory.buildPortDesc()
+ .setPortNo(OFPort.of(1))
+ .setHwAddr(MacAddress.of("01:02:03:04:05:06"))
+ .setName("interface1234567")
+ .setConfig(Sets.immutableEnumSet(OFPortConfig.NO_FWD, OFPortConfig.NO_PACKET_IN))
+ .setState(Sets.immutableEnumSet(OFPortState.LINK_DOWN, OFPortState.BLOCKED))
+ .setProperties(ImmutableList.<OFPortDescProp>of(factory.buildPortDescPropEthernet()
+ .setCurr(0x70)
+ .setMaxSpeed(0x80)
+ .build()))
+ .build())
+ );
diff --git a/test_data/of14/port_stats_reply.data b/test_data/of14/port_stats_reply.data
new file mode 100644
index 0000000..43dc471
--- /dev/null
+++ b/test_data/of14/port_stats_reply.data
@@ -0,0 +1,88 @@
+-- binary
+05 13 # version/type
+00 d8 # length
+00 00 00 05 # xid
+00 04 # stats_type
+00 00 # flags
+00 00 00 00 # pad
+00 78 # entries[0].length
+00 00 # pad
+00 00 00 01 # entries[0].port_no
+00 00 00 00 # entries[0].duration_sec
+00 00 00 00 # entries[0].duration_nsec
+00 00 00 00 00 00 00 01 # entries[0].rx_packets
+00 00 00 00 00 00 00 00 # entries[0].tx_packets
+00 00 00 00 00 00 00 00 # entries[0].rx_bytes
+00 00 00 00 00 00 00 00 # entries[0].tx_bytes
+00 00 00 00 00 00 00 00 # entries[0].rx_dropped
+00 00 00 00 00 00 00 00 # entries[0].tx_dropped
+00 00 00 00 00 00 00 00 # entries[0].rx_errors
+00 00 00 00 00 00 00 02 # entries[0].tx_errors
+00 00 # entries[0].properties[0].type (ethernet)
+00 28 # entries[0].properties[0].length
+00 00 00 00 # pad
+00 00 00 00 00 00 00 01 # entries[0].properties[0].rx_frame_err
+00 00 00 00 00 00 00 02 # entries[0].properties[0].rx_over_err
+00 00 00 00 00 00 00 03 # entries[0].properties[0].rx_crc_err
+00 00 00 00 00 00 00 04 # entries[0].properties[0].collisions
+00 50 # entries[1].length
+00 00 # pad
+ff ff ff fe # entries[1].port_no
+00 00 00 00 # entries[1].duration_sec
+00 00 00 00 # entries[1].duration_nsec
+00 00 00 00 00 00 00 03 # entries[1].rx_packets
+00 00 00 00 00 00 00 00 # entries[1].tx_packets
+00 00 00 00 00 00 00 00 # entries[1].rx_bytes
+00 00 00 00 00 00 00 00 # entries[1].tx_bytes
+00 00 00 00 00 00 00 00 # entries[1].rx_dropped
+00 00 00 00 00 00 00 00 # entries[1].tx_dropped
+00 00 00 00 00 00 00 00 # entries[1].rx_errors
+00 00 00 00 00 00 00 04 # entries[1].tx_errors
+-- python
+ofp.message.port_stats_reply(
+ xid=5, flags=0, entries=[
+ ofp.port_stats_entry(port_no=1, rx_packets=1, tx_errors=2,
+ properties=[
+ ofp.port_stats_prop.ethernet(
+ rx_frame_err=1,
+ rx_over_err=2,
+ rx_crc_err=3,
+ collisions=4)]),
+ ofp.port_stats_entry(port_no=ofp.OFPP_LOCAL, rx_packets=3, tx_errors=4)])
+-- c
+obj = of_port_stats_reply_new(OF_VERSION_1_4);
+{
+ of_object_t list;
+ of_port_stats_reply_entries_bind(obj, &list);
+ {
+ of_object_t *obj = of_port_stats_entry_new(OF_VERSION_1_4);
+ of_port_stats_entry_port_no_set(obj, 1);
+ of_port_stats_entry_rx_packets_set(obj, 1);
+ of_port_stats_entry_tx_packets_set(obj, 0);
+ of_port_stats_entry_rx_bytes_set(obj, 0);
+ of_port_stats_entry_tx_bytes_set(obj, 0);
+ of_port_stats_entry_rx_dropped_set(obj, 0);
+ of_port_stats_entry_tx_dropped_set(obj, 0);
+ of_port_stats_entry_rx_errors_set(obj, 0);
+ of_port_stats_entry_tx_errors_set(obj, 2);
+ /* TODO append property */
+ of_list_append(&list, obj);
+ of_object_delete(obj);
+ }
+ {
+ of_object_t *obj = of_port_stats_entry_new(OF_VERSION_1_4);
+ of_port_stats_entry_port_no_set(obj, OF_PORT_DEST_LOCAL);
+ of_port_stats_entry_rx_packets_set(obj, 3);
+ of_port_stats_entry_tx_packets_set(obj, 0);
+ of_port_stats_entry_rx_bytes_set(obj, 0);
+ of_port_stats_entry_tx_bytes_set(obj, 0);
+ of_port_stats_entry_rx_dropped_set(obj, 0);
+ of_port_stats_entry_tx_dropped_set(obj, 0);
+ of_port_stats_entry_rx_errors_set(obj, 0);
+ of_port_stats_entry_tx_errors_set(obj, 4);
+ of_list_append(&list, obj);
+ of_object_delete(obj);
+ }
+}
+of_port_stats_reply_flags_set(obj, 0);
+of_port_stats_reply_xid_set(obj, 5);
diff --git a/wireshark_gen/__init__.py b/wireshark_gen/__init__.py
index a610f3f..75918f8 100644
--- a/wireshark_gen/__init__.py
+++ b/wireshark_gen/__init__.py
@@ -38,7 +38,7 @@
DissectorField = namedtuple("DissectorField", ["fullname", "name", "type", "base", "enum_table"])
-proto_names = { 1: 'of10', 2: 'of11', 3: 'of12', 4: 'of13' }
+proto_names = { 1: 'of10', 2: 'of11', 3: 'of12', 4: 'of13', 5: 'of14' }
def make_field_name(version, ofclass_name, member_name):
return "%s.%s.%s" % (proto_names[version.wire_version],
ofclass_name[3:],