Merge branch 'master' of https://github.com/floodlight/loxigen
diff --git a/.abat-automerge b/.abat-automerge
index 36e8739..772134b 100755
--- a/.abat-automerge
+++ b/.abat-automerge
@@ -4,3 +4,7 @@
ln -sf ../../.hooks/pre-commit .git/hooks/pre-commit
make all check-all
+
+if [[ ${ARTIFACT_REPO_URL-} ]]; then
+ ./.build/push-artifacts.sh ${ARTIFACT_REPO_URL}
+fi
diff --git a/.build/push-artifacts.sh b/.build/push-artifacts.sh
new file mode 100755
index 0000000..fd607eb
--- /dev/null
+++ b/.build/push-artifacts.sh
@@ -0,0 +1,60 @@
+#!/bin/bash -eu
+
+# Push the loxigen artifacts to a dedicated git repository,
+# along with a nice commit message and a tag
+
+ARTIFACT_REPO_URL="$1"
+if [[ ! $ARTIFACT_REPO_URL ]]; then
+ echo "Call syntax: $0 <artifact_repo_url>" >&2
+ exit 1
+fi
+
+ARTIFACT_REPO=$(mktemp -d --tmpdir "push-artifacts-repo.XXXXXXX")
+
+git clone ${ARTIFACT_REPO_URL} ${ARTIFACT_REPO}
+find ${ARTIFACT_REPO} -mindepth 1 -maxdepth 1 -type d \! -name '.*' -print0 | xargs -0 rm -r
+make LOXI_OUTPUT_DIR=${ARTIFACT_REPO} clean all
+
+loxi_head=$(git rev-parse HEAD)
+last_loxi_log=$(git log --format=oneline -1)
+git_log_file=$(mktemp --tmpdir "git-log-file.XXXXXXX")
+
+last_loxi_revision=""
+
+if [[ -e "${ARTIFACT_REPO}/loxi-revision" ]]; then
+ last_loxi_revision=$(cat "${ARTIFACT_REPO}/loxi-revision" | cut -d ' ' -f 1)
+ if [[ $(git cat-file -t "$last_loxi_revision" 2>/dev/null) != "commit" ]]; then
+ echo "Last loxi revision ${last_loxi_revision} specified in ${ARTIFACT_REPO_URL}/loxi-revision not found in loxigen repo"
+ last_loxi_revision=""
+ fi
+fi
+
+if [[ $last_loxi_revision ]]; then
+ echo "Last loxi revision committed: $last_loxi_revision"
+ git log $last_loxi_revision..${loxi_head} >>$git_log_file
+ loxi_github_url="https://github.com/floodlight/loxigen/compare/${last_loxi_revision}...${loxi_head}"
+else
+ echo "No Previous loxi revision info found"
+ git log -1 HEAD >>$git_log_file
+ loxi_github_url="https://github.com/floodlight/loxigen/commit/${loxi_head}"
+fi
+
+
+(
+ set -xe
+ cd $ARTIFACT_REPO
+ echo $last_loxi_log >loxi-revision
+ git add -A
+
+ (
+ echo "Artifacts from ${loxi_github_url}"
+ echo
+ echo "Loxigen Head commit floodlight/loxigen@${loxi_head}"
+ cat $git_log_file
+ ) | git commit --file=-
+
+ git tag -a -f "loxi/${loxi_head}" -m "Tag Loxigen Revision ${loxi_head}"
+ git push
+)
+
+rm -rf ${ARTIFACT_REPO}
diff --git a/Makefile b/Makefile
index 4712a04..fc9c6e4 100644
--- a/Makefile
+++ b/Makefile
@@ -43,9 +43,10 @@
\! \( -name '*.cache' -o -name '.*' \))
INPUT_FILES = $(wildcard openflow_input/*)
TEST_DATA = $(shell find test_data -name '*.data')
-OPENFLOWJ_WORKSPACE = openflowj-loxi
+OPENFLOWJ_OUTPUT_DIR = ${LOXI_OUTPUT_DIR}/openflowj
+OPENFLOWJ_ECLIPSE_WORKSPACE = openflowj-loxi
-all: c python java
+all: c python java wireshark
c: .loxi_ts.c
@@ -69,20 +70,35 @@
@echo "HTML documentation output to ${LOXI_OUTPUT_DIR}/pyloxi-doc"
java: .loxi_ts.java
- mkdir -p ${OPENFLOWJ_WORKSPACE}
- ln -sf ../java_gen/pre-written/pom.xml ${OPENFLOWJ_WORKSPACE}/pom.xml
- ln -sf ../java_gen/pre-written/LICENSE.txt ${OPENFLOWJ_WORKSPACE}/LICENSE.txt
- ln -sf ../java_gen/pre-written/src ${OPENFLOWJ_WORKSPACE}/src
- rsync --checksum --delete -rv ${LOXI_OUTPUT_DIR}/openflowj/src/ ${OPENFLOWJ_WORKSPACE}/gen-src
+ @rsync -rt java_gen/pre-written/ ${LOXI_OUTPUT_DIR}/openflowj/
+ @if [ -e ${OPENFLOWJ_ECLIPSE_WORKSPACE} ]; then \
+ rsync --checksum --delete -rv ${LOXI_OUTPUT_DIR}/openflowj/gen-src/ ${OPENFLOWJ_ECLIPSE_WORKSPACE}/gen-src; \
+ fi
.loxi_ts.java: ${LOXI_PY_FILES} ${LOXI_TEMPLATE_FILES} ${INPUT_FILES} ${TEST_DATA}
./loxigen.py --install-dir=${LOXI_OUTPUT_DIR} --lang=java
touch $@
-java-eclipse: java
- cd ${OPENFLOWJ_WORKSPACE} && mvn eclipse:eclipse
+eclipse-workspace:
+ mkdir -p ${OPENFLOWJ_ECLIPSE_WORKSPACE}
+ ln -sf ../java_gen/pre-written/pom.xml ${OPENFLOWJ_ECLIPSE_WORKSPACE}/pom.xml
+ ln -sf ../java_gen/pre-written/LICENSE.txt ${OPENFLOWJ_ECLIPSE_WORKSPACE}/LICENSE.txt
+ ln -sf ../java_gen/pre-written/src ${OPENFLOWJ_ECLIPSE_WORKSPACE}
+ cd ${OPENFLOWJ_ECLIPSE_WORKSPACE} && mvn eclipse:eclipse
# Unfortunately, mvn eclipse:eclipse resolves the symlink, which doesn't work with eclipse
- cd ${OPENFLOWJ_WORKSPACE} && perl -pi -e 's{<classpathentry kind="src" path="[^"]*/java_gen/pre-written/src/}{<classpathentry kind="src" path="src/}' .classpath
+ cd ${OPENFLOWJ_ECLIPSE_WORKSPACE} && perl -pi -e 's{<classpathentry kind="src" path="[^"]*/java_gen/pre-written/src/}{<classpathentry kind="src" path="src/}' .classpath
+
+check-java: java
+ cd ${OPENFLOWJ_OUTPUT_DIR} && mvn compile test-compile test
+
+package-java: java
+ cd ${OPENFLOWJ_OUTPUT_DIR} && mvn package
+
+deploy-java: java
+ cd ${OPENFLOWJ_OUTPUT_DIR} && mvn deploy
+
+install-java: java
+ cd ${OPENFLOWJ_OUTPUT_DIR} && mvn install
wireshark: .loxi_ts.wireshark
@@ -119,18 +135,6 @@
make -C ${LOXI_OUTPUT_DIR}/locitest
${LOXI_OUTPUT_DIR}/locitest/locitest
-check-java: java
- cd ${OPENFLOWJ_WORKSPACE} && mvn compile test-compile test
-
-package-java: java
- cd ${OPENFLOWJ_WORKSPACE} && mvn package
-
-deploy-java: java
- cd ${OPENFLOWJ_WORKSPACE} && mvn deploy
-
-install-java: java
- cd ${OPENFLOWJ_WORKSPACE} && mvn install
-
pylint:
pylint -E ${LOXI_PY_FILES}
diff --git a/c_gen/templates/loci_show.h b/c_gen/templates/loci_show.h
index 04d863f..c61866c 100644
--- a/c_gen/templates/loci_show.h
+++ b/c_gen/templates/loci_show.h
@@ -362,5 +362,6 @@
#define LOCI_SHOW_u16_partner_port_priority(writer, cookie, val) LOCI_SHOW_u16(writer, cookie, val)
#define LOCI_SHOW_u16_partner_port_num(writer, cookie, val) LOCI_SHOW_u16(writer, cookie, val)
#define LOCI_SHOW_u16_partner_key(writer, cookie, val) LOCI_SHOW_u16(writer, cookie, val)
+#define LOCI_SHOW_u64_time_ms(writer, cookie, val) LOCI_SHOW_u64(writer, cookie, val)
#endif /* _LOCI_SHOW_H_ */
diff --git a/java_gen/codegen.py b/java_gen/codegen.py
index c01ba68..9a10bdf 100644
--- a/java_gen/codegen.py
+++ b/java_gen/codegen.py
@@ -73,7 +73,7 @@
def render_class(self, clazz, template, src_dir=None, **context):
if not src_dir:
- src_dir = "src/main/java/"
+ src_dir = "gen-src/main/java/"
context['class_name'] = clazz.name
context['package'] = clazz.package
@@ -147,7 +147,7 @@
unit_test = unit_tests.get_test_unit(i)
if unit_test.has_test_data:
self.render_class(clazz=unit_test,
- template='unit_test.java', src_dir="src/test/java",
+ template='unit_test.java', src_dir="gen-src/test/java",
version=unit_test.java_class.version,
test=unit_test, msg=unit_test.java_class,
test_data=unit_test.test_data)
diff --git a/java_gen/java_model.py b/java_gen/java_model.py
index 824a320..f90c1f2 100644
--- a/java_gen/java_model.py
+++ b/java_gen/java_model.py
@@ -71,95 +71,6 @@
# interfaces that are virtual
virtual_interfaces = set(['OFOxm', 'OFInstruction', 'OFFlowMod', 'OFBsnVport' ])
- OxmMapEntry = namedtuple("OxmMapEntry", ["type_name", "value", "masked" ])
- oxm_map = { "OFOxmInPort": OxmMapEntry("OFPort", "IN_PORT", False),
- "OFOxmInPortMasked": OxmMapEntry("OFPort", "IN_PORT", True),
- "OFOxmInPhyPort": OxmMapEntry("OFPort", "IN_PHY_PORT", False),
- "OFOxmInPhyPortMasked": OxmMapEntry("OFPort", "IN_PHY_PORT", True),
- "OFOxmMetadata": OxmMapEntry("OFMetadata", "METADATA", False),
- "OFOxmMetadataMasked": OxmMapEntry("OFMetadata", "METADATA", True),
- "OFOxmEthDst": OxmMapEntry("MacAddress", "ETH_DST", False),
- "OFOxmEthDstMasked": OxmMapEntry("MacAddress", "ETH_DST", True),
- "OFOxmEthSrc": OxmMapEntry("MacAddress", "ETH_SRC", False),
- "OFOxmEthSrcMasked": OxmMapEntry("MacAddress", "ETH_SRC", True),
- "OFOxmEthType": OxmMapEntry("EthType", "ETH_TYPE", False),
- "OFOxmEthTypeMasked": OxmMapEntry("EthType", "ETH_TYPE", True),
- "OFOxmVlanVid": OxmMapEntry("OFVlanVidMatch", "VLAN_VID", False),
- "OFOxmVlanVidMasked": OxmMapEntry("OFVlanVidMatch", "VLAN_VID", True),
- "OFOxmVlanPcp": OxmMapEntry("VlanPcp", "VLAN_PCP", False),
- "OFOxmVlanPcpMasked": OxmMapEntry("VlanPcp", "VLAN_PCP", True),
- "OFOxmIpDscp": OxmMapEntry("IpDscp", "IP_DSCP", False),
- "OFOxmIpDscpMasked": OxmMapEntry("IpDscp", "IP_DSCP", True),
- "OFOxmIpEcn": OxmMapEntry("IpEcn", "IP_ECN", False),
- "OFOxmIpEcnMasked": OxmMapEntry("IpEcn", "IP_ECN", True),
- "OFOxmIpProto": OxmMapEntry("IpProtocol", "IP_PROTO", False),
- "OFOxmIpProtoMasked": OxmMapEntry("IpProtocol", "IP_PROTO", True),
- "OFOxmIpv4Src": OxmMapEntry("IPv4Address", "IPV4_SRC", False),
- "OFOxmIpv4SrcMasked": OxmMapEntry("IPv4Address", "IPV4_SRC", True),
- "OFOxmIpv4Dst": OxmMapEntry("IPv4Address", "IPV4_DST", False),
- "OFOxmIpv4DstMasked": OxmMapEntry("IPv4Address", "IPV4_DST", True),
- "OFOxmTcpSrc": OxmMapEntry("TransportPort", "TCP_SRC", False),
- "OFOxmTcpSrcMasked": OxmMapEntry("TransportPort", "TCP_SRC", True),
- "OFOxmTcpDst": OxmMapEntry("TransportPort", "TCP_DST", False),
- "OFOxmTcpDstMasked": OxmMapEntry("TransportPort", "TCP_DST", True),
- "OFOxmUdpSrc": OxmMapEntry("TransportPort", "UDP_SRC", False),
- "OFOxmUdpSrcMasked": OxmMapEntry("TransportPort", "UDP_SRC", True),
- "OFOxmUdpDst": OxmMapEntry("TransportPort", "UDP_DST", False),
- "OFOxmUdpDstMasked": OxmMapEntry("TransportPort", "UDP_DST", True),
- "OFOxmSctpSrc": OxmMapEntry("TransportPort", "SCTP_SRC", False),
- "OFOxmSctpSrcMasked": OxmMapEntry("TransportPort", "SCTP_SRC", True),
- "OFOxmSctpDst": OxmMapEntry("TransportPort", "SCTP_DST", False),
- "OFOxmSctpDstMasked": OxmMapEntry("TransportPort", "SCTP_DST", True),
- "OFOxmIcmpv4Type": OxmMapEntry("ICMPv4Type", "ICMPV4_TYPE", False),
- "OFOxmIcmpv4TypeMasked": OxmMapEntry("ICMPv4Type", "ICMPV4_TYPE", True),
- "OFOxmIcmpv4Code": OxmMapEntry("ICMPv4Code", "ICMPV4_CODE", False),
- "OFOxmIcmpv4CodeMasked": OxmMapEntry("ICMPv4Code", "ICMPV4_CODE", True),
- "OFOxmArpOp": OxmMapEntry("ArpOpcode", "ARP_OP", False),
- "OFOxmArpOpMasked": OxmMapEntry("ArpOpcode", "ARP_OP", True),
- "OFOxmArpSpa": OxmMapEntry("IPv4Address", "ARP_SPA", False),
- "OFOxmArpSpaMasked": OxmMapEntry("IPv4Address", "ARP_SPA", True),
- "OFOxmArpTpa": OxmMapEntry("IPv4Address", "ARP_TPA", False),
- "OFOxmArpTpaMasked": OxmMapEntry("IPv4Address", "ARP_TPA", True),
- "OFOxmArpSha": OxmMapEntry("MacAddress", "ARP_SHA", False),
- "OFOxmArpShaMasked": OxmMapEntry("MacAddress", "ARP_SHA", True),
- "OFOxmArpTha": OxmMapEntry("MacAddress", "ARP_THA", False),
- "OFOxmArpThaMasked": OxmMapEntry("MacAddress", "ARP_THA", True),
- "OFOxmIpv6Src": OxmMapEntry("IPv6Address", "IPV6_SRC", False),
- "OFOxmIpv6SrcMasked": OxmMapEntry("IPv6Address", "IPV6_SRC", True),
- "OFOxmIpv6Dst": OxmMapEntry("IPv6Address", "IPV6_DST", False),
- "OFOxmIpv6DstMasked": OxmMapEntry("IPv6Address", "IPV6_DST", True),
- "OFOxmIpv6Flabel": OxmMapEntry("IPv6FlowLabel", "IPV6_FLABEL", False),
- "OFOxmIpv6FlabelMasked": OxmMapEntry("IPv6FlowLabel", "IPV6_FLABEL", True),
- "OFOxmIcmpv6Type": OxmMapEntry("U8", "ICMPV6_TYPE", False),
- "OFOxmIcmpv6TypeMasked": OxmMapEntry("U8", "ICMPV6_TYPE", True),
- "OFOxmIcmpv6Code": OxmMapEntry("U8", "ICMPV6_CODE", False),
- "OFOxmIcmpv6CodeMasked": OxmMapEntry("U8", "ICMPV6_CODE", True),
- "OFOxmIpv6NdTarget": OxmMapEntry("IPv6Address", "IPV6_ND_TARGET", False),
- "OFOxmIpv6NdTargetMasked": OxmMapEntry("IPv6Address", "IPV6_ND_TARGET", True),
- "OFOxmIpv6NdSll": OxmMapEntry("MacAddress", "IPV6_ND_SLL", False),
- "OFOxmIpv6NdSllMasked": OxmMapEntry("MacAddress", "IPV6_ND_SLL", True),
- "OFOxmIpv6NdTll": OxmMapEntry("MacAddress", "IPV6_ND_TLL", False),
- "OFOxmIpv6NdTllMasked": OxmMapEntry("MacAddress", "IPV6_ND_TLL", True),
- "OFOxmMplsLabel": OxmMapEntry("U32", "MPLS_LABEL", False),
- "OFOxmMplsLabelMasked": OxmMapEntry("U32", "MPLS_LABEL", True),
- "OFOxmMplsTc": OxmMapEntry("U8", "MPLS_TC", False),
- "OFOxmMplsTcMasked": OxmMapEntry("U8", "MPLS_TC", True),
- "OFOxmBsnInPorts128": OxmMapEntry("OFBitMask128", "BSN_IN_PORTS_128", False),
- "OFOxmBsnInPorts128Masked": OxmMapEntry("OFBitMask128", "BSN_IN_PORTS_128", True),
- "OFOxmBsnLagId": OxmMapEntry("LagId", "BSN_LAG_ID", False),
- "OFOxmBsnLagIdMasked": OxmMapEntry("LagId", "BSN_LAG_ID", True),
- "OFOxmBsnVrf": OxmMapEntry("VRF", "BSN_VRF", False),
- "OFOxmBsnVrfMasked": OxmMapEntry("VRF", "BSN_VRF", True),
- "OFOxmBsnGlobalVrfAllowed": OxmMapEntry("OFBooleanValue", "BSN_GLOBAL_VRF_ALLOWED", False),
- "OFOxmBsnGlobalVrfAllowedMasked": OxmMapEntry("OFBooleanValue", "BSN_GLOBAL_VRF_ALLOWED", True),
- "OFOxmBsnL3InterfaceClassId": OxmMapEntry("ClassId", "BSN_L3_INTERFACE_CLASS_ID", False),
- "OFOxmBsnL3InterfaceClassIdMasked": OxmMapEntry("ClassId", "BSN_L3_INTERFACE_CLASS_ID", True),
- "OFOxmBsnL3SrcClassId": OxmMapEntry("ClassId", "BSN_L3_SRC_CLASS_ID", False),
- "OFOxmBsnL3SrcClassIdMasked": OxmMapEntry("ClassId", "BSN_L3_SRC_CLASS_ID", True),
- "OFOxmBsnL3DstClassId": OxmMapEntry("ClassId", "BSN_L3_DST_CLASS_ID", False),
- "OFOxmBsnL3DstClassIdMasked": OxmMapEntry("ClassId", "BSN_L3_DST_CLASS_ID", True),
- }
-
# Registry of nullable properties:
# ${java_class_name} -> set(${java_property_name})
nullable_map = defaultdict(lambda: set(),
@@ -182,6 +93,12 @@
OFTableConfig = (
MaskedEnumGroup("table_miss_flags", mask="TABLE_MISS_MASK", members=set(("TABLE_MISS_CONTROLLER", "TABLE_MISS_CONTINUE", "TABLE_MISS_DROP"))),
),
+ OFGetConfigReply = (
+ MaskedEnumGroup("flags", mask="OFP_FRAG_MASK", members=set(("FRAG_NORMAL", "FRAG_DROP", "FRAG_REASM"))),
+ ),
+ OFSetConfig = (
+ MaskedEnumGroup("flags", mask="OFP_FRAG_MASK", members=set(("FRAG_NORMAL", "FRAG_DROP", "FRAG_REASM"))),
+ ),
)
# represents a metadata property associated with an EnumClass
@@ -342,6 +259,14 @@
else:
return True
+ @property
+ @memoize
+ def oxm_map(self):
+ OxmMapEntry = namedtuple("OxmMapEntry", ["type_name", "value", "masked" ])
+ return OrderedDict( (oxm.name, OxmMapEntry(type_name=oxm.member_by_name("value").java_type.public_type,
+ value=re.sub(r'^of_oxm_', r'', re.sub(r'_masked$', r'', oxm.ir_class.name)).upper(),
+ masked=oxm.ir_class.name.endswith("_masked")))
+ for oxm in self.interfaces if oxm.ir_class.is_subclassof("of_oxm") )
class OFFactory(namedtuple("OFFactory", ("package", "name", "members", "remove_prefix", "base_class", "sub_factories", "xid_generator"))):
@property
@@ -549,8 +474,8 @@
elif self.name == "OFOxm":
return ("oxm", None, "T extends OFValueType<T>")
elif loxi_utils.class_is_oxm(self.c_name):
- if self.name in model.oxm_map:
- return ("oxm", "OFOxm<%s>" % model.oxm_map[self.name].type_name, None)
+ if self.member_by_name("value") is not None:
+ return ("oxm", "OFOxm<%s>" % self.member_by_name("value").java_type.public_type, None)
else:
return ("oxm", "OFOxm", None)
elif loxi_utils.class_is_instruction(self.c_name):
@@ -629,14 +554,16 @@
JavaVirtualMember(self, "canonical", java_type.make_oxm_jtype("T"))
]
elif self.ir_class.is_subclassof("of_oxm"):
- field_type = java_type.make_match_field_jtype(model.oxm_map[self.name].type_name) \
- if self.name in model.oxm_map \
- else java_type.make_match_field_jtype()
+ value = find(lambda m: m.name=="value", self.ir_model_members)
+ if value:
+ field_type = java_type.make_match_field_jtype(value.java_type.public_type)
+ else:
+ field_type = java_type.make_match_field_jtype()
virtual_members += [
JavaVirtualMember(self, "matchField", field_type),
JavaVirtualMember(self, "masked", java_type.boolean),
- JavaVirtualMember(self, "canonical", java_type.make_oxm_jtype(model.oxm_map[self.name].type_name),
+ JavaVirtualMember(self, "canonical", java_type.make_oxm_jtype(value.java_type.public_type),
custom_template=lambda builder: "OFOxm{}_getCanonical.java".format(".Builder" if builder else "")),
]
if not find(lambda x: x.name == "mask", self.ir_model_members):
@@ -760,11 +687,12 @@
@property
def virtual_members(self):
virtual_members = []
- if self.interface.parent_interface and self.interface.parent_interface.startswith("OFOxm"):
- if self.interface.name in model.oxm_map:
+ if self.ir_class.is_subclassof("of_oxm"):
+ value_member = find(lambda m: m.name, self.ir_model_members)
+ if value_member:
oxm_entry = model.oxm_map[self.interface.name]
virtual_members += [
- JavaVirtualMember(self, "matchField", java_type.make_match_field_jtype(oxm_entry.type_name), "MatchField.%s" % oxm_entry.value),
+ JavaVirtualMember(self, "matchField", java_type.make_match_field_jtype(value_member.java_type.public_type), "MatchField.%s" % oxm_entry.value),
JavaVirtualMember(self, "masked", java_type.boolean, "true" if oxm_entry.masked else "false"),
]
else:
@@ -883,7 +811,7 @@
entry = enum.entry_by_version_value(self.msg.version, self.value)
return "%s.%s" % ( enum.name, entry.name)
except KeyError, e:
- print e.message
+ logger.debug("No enum found", e)
return self.value
@property
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFVlanVidMatch.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFVlanVidMatch.java
index 29d6e02..fddaa5d 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFVlanVidMatch.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFVlanVidMatch.java
@@ -4,6 +4,8 @@
import org.jboss.netty.buffer.ChannelBuffer;
import org.projectfloodlight.openflow.exceptions.OFParseError;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.google.common.hash.PrimitiveSink;
import com.google.common.primitives.Shorts;
@@ -21,6 +23,7 @@
*
*/
public class OFVlanVidMatch implements OFValueType<OFVlanVidMatch> {
+ private static final Logger logger = LoggerFactory.getLogger(OFVlanVidMatch.class);
private static final short VALIDATION_MASK = 0x1FFF;
private static final short PRESENT_VAL = 0x1000;
@@ -59,7 +62,11 @@
return UNTAGGED;
else if(vid == PRESENT_VAL)
return PRESENT;
- else if ((vid & VALIDATION_MASK) != vid)
+ else if(vid == UNTAGGED_VAL_OF10) {
+ // workaround for IVS sometimes sending 0F1.0 untagged (0xFFFF) values
+ logger.warn("Warning: received OF1.0 untagged vlan value (0xFFFF) in OF1.3 VlanVid. Treating as UNTAGGED");
+ return UNTAGGED;
+ } else if ((vid & VALIDATION_MASK) != vid)
throw new IllegalArgumentException(String.format("Illegal VLAN value: %x", vid));
return new OFVlanVidMatch(vid);
}
diff --git a/java_gen/templates/custom/OFMatchV3Ver13.java b/java_gen/templates/custom/OFMatchV3Ver13.java
index 9bfb234..24cab5b 100644
--- a/java_gen/templates/custom/OFMatchV3Ver13.java
+++ b/java_gen/templates/custom/OFMatchV3Ver13.java
@@ -1,4 +1,5 @@
-
+//:: 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 {
@@ -33,36 +34,9 @@
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:
- case BSN_IN_PORTS_128:
+ //:: 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;
diff --git a/java_gen/templates/of_class.java b/java_gen/templates/of_class.java
index 4057b3d..b35df1c 100644
--- a/java_gen/templates/of_class.java
+++ b/java_gen/templates/of_class.java
@@ -430,5 +430,4 @@
return result;
}
-
}
diff --git a/java_gen/templates/of_factory_class.java b/java_gen/templates/of_factory_class.java
index deb6e53..ef26ca0 100644
--- a/java_gen/templates/of_factory_class.java
+++ b/java_gen/templates/of_factory_class.java
@@ -121,7 +121,7 @@
return (OFOxm<F>)((Object)${method_name}((${type_name})((Object)value)));
//:: #endfor
default:
- return null;
+ throw new IllegalArgumentException("No OXM known for match field " + field);
}
}
@@ -140,7 +140,7 @@
return (OFOxm<F>)((Object)${method_name}((${type_name})((Object)value), (${type_name})((Object)mask)));
//:: #endfor
default:
- return null;
+ throw new IllegalArgumentException("No OXM known for match field " + field);
}
}
diff --git a/java_gen/test.sh b/java_gen/test.sh
deleted file mode 100755
index 7b71ffd..0000000
--- a/java_gen/test.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/bin/sh
-
-rm -rf target_code/
-cd ..
-./loxigen.py -ljava #&& ( cd target_code/Modules/openflowj/ && ant )
diff --git a/loxi_ir/ir.py b/loxi_ir/ir.py
index e2c4a34..8553f62 100644
--- a/loxi_ir/ir.py
+++ b/loxi_ir/ir.py
@@ -360,7 +360,7 @@
member = ir_class(offset = length_info.offset,
base_length = length_info.base_length,
is_fixed_length=length_info.is_fixed_length,
- **convert_member_properties(vars(fe_member)))
+ **convert_member_properties(fe_member._asdict()))
member.of_class = of_class
return member
diff --git a/openflow_input/bsn_time b/openflow_input/bsn_time
new file mode 100644
index 0000000..0a955be
--- /dev/null
+++ b/openflow_input/bsn_time
@@ -0,0 +1,54 @@
+// 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.
+
+// Request a timestamp during message processing.
+//
+// The timestamp is relative to when the switch sent the initial HELLO.
+// The intended use is in conjunction with barriers to approximately determine
+// time elapsed between processing two messages (such as stats requests).
+// The timestamp must be monotonic (not affected by system time updates).
+
+#version 4
+
+struct of_bsn_time_request : of_bsn_header {
+ uint8_t version;
+ uint8_t type == 4;
+ uint16_t length;
+ uint32_t xid;
+ uint32_t experimenter == 0x5c16c7;
+ uint32_t subtype == 44;
+};
+
+struct of_bsn_time_reply : of_bsn_header {
+ uint8_t version;
+ uint8_t type == 4;
+ uint16_t length;
+ uint32_t xid;
+ uint32_t experimenter == 0x5c16c7;
+ uint32_t subtype == 45;
+ uint64_t time_ms; /* Milliseconds since HELLO */
+};
diff --git a/openflow_input/standard-1.0 b/openflow_input/standard-1.0
index ad2e76f..1df03bb 100644
--- a/openflow_input/standard-1.0
+++ b/openflow_input/standard-1.0
@@ -190,7 +190,7 @@
OFPC_ARP_MATCH_IP = 0x80,
};
-enum ofp_config_flags(wire_type=uint32_t, bitmask=True) {
+enum ofp_config_flags(wire_type=uint16_t, bitmask=True) {
OFPC_FRAG_NORMAL = 0x0,
OFPC_FRAG_DROP = 0x1,
OFPC_FRAG_REASM = 0x2,
@@ -371,7 +371,7 @@
uint8_t type == 8;
uint16_t length;
uint32_t xid;
- uint16_t flags;
+ enum ofp_config_flags flags;
uint16_t miss_send_len;
};
@@ -380,7 +380,7 @@
uint8_t type == 9;
uint16_t length;
uint32_t xid;
- uint16_t flags;
+ enum ofp_config_flags flags;
uint16_t miss_send_len;
};
diff --git a/openflow_input/standard-1.1 b/openflow_input/standard-1.1
index 906519c..a9aac6b 100644
--- a/openflow_input/standard-1.1
+++ b/openflow_input/standard-1.1
@@ -477,7 +477,7 @@
uint8_t type == 8;
uint16_t length;
uint32_t xid;
- uint16_t flags;
+ enum ofp_config_flags flags;
uint16_t miss_send_len;
};
@@ -486,7 +486,7 @@
uint8_t type == 9;
uint16_t length;
uint32_t xid;
- uint16_t flags;
+ enum ofp_config_flags flags;
uint16_t miss_send_len;
};
@@ -1241,7 +1241,7 @@
struct of_group_desc_stats_entry {
uint16_t length;
- uint8_t group_type;
+ enum ofp_group_type group_type;
pad(1);
uint32_t group_id;
list(of_bucket_t) buckets;
diff --git a/openflow_input/standard-1.2 b/openflow_input/standard-1.2
index 90447f5..c1e8a2b 100644
--- a/openflow_input/standard-1.2
+++ b/openflow_input/standard-1.2
@@ -515,7 +515,7 @@
uint8_t type == 8;
uint16_t length;
uint32_t xid;
- uint16_t flags;
+ enum ofp_config_flags flags;
uint16_t miss_send_len;
};
@@ -524,7 +524,7 @@
uint8_t type == 9;
uint16_t length;
uint32_t xid;
- uint16_t flags;
+ enum ofp_config_flags flags;
uint16_t miss_send_len;
};
@@ -1208,7 +1208,7 @@
struct of_group_desc_stats_entry {
uint16_t length;
- uint8_t group_type;
+ enum ofp_group_type group_type;
pad(1);
uint32_t group_id;
list(of_bucket_t) buckets;
diff --git a/openflow_input/standard-1.3 b/openflow_input/standard-1.3
index 4d0ca7e..87adcc4 100644
--- a/openflow_input/standard-1.3
+++ b/openflow_input/standard-1.3
@@ -648,7 +648,7 @@
uint8_t type == 8;
uint16_t length;
uint32_t xid;
- uint16_t flags;
+ enum ofp_config_flags flags;
uint16_t miss_send_len;
};
@@ -657,7 +657,7 @@
uint8_t type == 9;
uint16_t length;
uint32_t xid;
- uint16_t flags;
+ enum ofp_config_flags flags;
uint16_t miss_send_len;
};
@@ -1427,7 +1427,7 @@
struct of_group_desc_stats_entry {
uint16_t length;
- uint8_t group_type;
+ enum ofp_group_type group_type;
pad(1);
uint32_t group_id;
list(of_bucket_t) buckets;
diff --git a/test_data/of13/get_config_reply.data b/test_data/of13/get_config_reply.data
index 111ac61..66ea834 100644
--- a/test_data/of13/get_config_reply.data
+++ b/test_data/of13/get_config_reply.data
@@ -9,3 +9,8 @@
xid=0x12345678,
flags=ofp.OFPC_FRAG_REASM,
miss_send_len=0xffff)
+-- java
+builder.setXid(0x12345678)
+ .setFlags(Sets.immutableEnumSet(OFConfigFlags.FRAG_REASM))
+ .setMissSendLen(0xffff)
+ .build()
diff --git a/wireshark_gen/templates/openflow.lua b/wireshark_gen/templates/openflow.lua
index 7113281..d9eb76a 100644
--- a/wireshark_gen/templates/openflow.lua
+++ b/wireshark_gen/templates/openflow.lua
@@ -29,6 +29,14 @@
:: ir = loxi_globals.ir
:: include('_copyright.lua')
+-- Copy this file to your wireshark plugin directory:
+-- Linux / OS X: ~/.wireshark/plugins/
+-- Windows: C:\Documents and Settings\<username>\Application Data\Wireshark\plugins\
+-- You may need to create the directory.
+
+-- The latest version of this dissector is always available at:
+-- http://www.projectfloodlight.org/openflow.lua
+
:: include('_ofreader.lua')
:: include('_oftype_readers.lua')